You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2018/03/01 22:31:11 UTC
[ambari] branch trunk updated: AMBARI-23111 Additional fixes for
service summary page to support NameNode Federation. (ababiichuk)
This is an automated email from the ASF dual-hosted git repository.
ababiichuk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push:
new c635b09 AMBARI-23111 Additional fixes for service summary page to support NameNode Federation. (ababiichuk)
c635b09 is described below
commit c635b09e8ce153b3d50f1c929575b2f0910ed7ca
Author: ababiichuk <ab...@hortonworks.com>
AuthorDate: Wed Feb 28 20:30:24 2018 +0200
AMBARI-23111 Additional fixes for service summary page to support NameNode Federation. (ababiichuk)
---
.../app/controllers/global/update_controller.js | 4 +-
.../main/host/bulk_operations_controller.js | 6 +-
ambari-web/app/controllers/main/host/details.js | 4 +-
ambari-web/app/controllers/main/service/item.js | 149 ++++++++++++++-------
ambari-web/app/mappers/hosts_mapper.js | 3 +-
ambari-web/app/mappers/service_metrics_mapper.js | 112 ++++++++++------
ambari-web/app/messages.js | 12 +-
ambari-web/app/models/host_component.js | 3 +-
ambari-web/app/models/service/hdfs.js | 11 +-
ambari-web/app/styles/alerts.less | 26 +---
ambari-web/app/styles/application.less | 7 +-
ambari-web/app/styles/common.less | 10 ++
.../app/styles/enhanced_service_dashboard.less | 20 +--
ambari-web/app/styles/hosts.less | 4 +-
ambari-web/app/styles/stack_versions.less | 4 +-
ambari-web/app/styles/visualsearch.less | 4 +-
ambari-web/app/styles/wizard.less | 15 +--
.../app/templates/main/service/info/summary.hbs | 15 +--
.../service/info/summary/master_components.hbs | 72 +++++-----
ambari-web/app/templates/main/service/item.hbs | 8 +-
ambari-web/app/utils/ajax/ajax.js | 2 +-
ambari-web/app/views/common/chart/linear_time.js | 1 +
.../app/views/common/quick_view_link_view.js | 32 +++--
.../app/views/main/dashboard/widgets/hdfs_links.js | 2 +
.../views/main/dashboard/widgets/namenode_cpu.js | 1 +
.../details/host_component_views/datanode_view.js | 1 +
.../main/service/info/components_list_view.js | 16 +--
ambari-web/app/views/main/service/info/summary.js | 13 +-
ambari-web/app/views/main/service/item.js | 3 +
.../controllers/global/update_controller_test.js | 2 +-
.../test/controllers/main/service/item_test.js | 20 +--
.../test/views/common/quick_link_view_test.js | 15 +--
32 files changed, 333 insertions(+), 264 deletions(-)
diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js
index 3ead4e8..22cadc9 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -67,7 +67,8 @@ App.UpdateController = Em.Controller.extend({
"host_components/metrics/hbase/master/MasterActiveTime," +
"host_components/metrics/hbase/master/AverageLoad," +
"host_components/metrics/master/AssignmentManger/ritCount",
- 'STORM': 'metrics/api/v1/cluster/summary,metrics/api/v1/topology/summary,metrics/api/v1/nimbus/summary'
+ 'STORM': 'metrics/api/v1/cluster/summary,metrics/api/v1/topology/summary,metrics/api/v1/nimbus/summary',
+ 'HDFS': 'host_components/metrics/dfs/namenode/ClusterId'
},
/**
@@ -224,6 +225,7 @@ App.UpdateController = Em.Controller.extend({
realUrl = '/hosts?fields=Hosts/rack_info,Hosts/host_name,Hosts/maintenance_state,Hosts/public_host_name,Hosts/cpu_count,Hosts/ph_cpu_count,Hosts/last_agent_env,' +
'alerts_summary,Hosts/host_status,Hosts/host_state,Hosts/last_heartbeat_time,Hosts/ip,host_components/HostRoles/state,host_components/HostRoles/maintenance_state,' +
'host_components/HostRoles/stale_configs,host_components/HostRoles/service_name,host_components/HostRoles/display_name,host_components/HostRoles/desired_admin_state,' +
+ (App.Service.find().someProperty('serviceName', 'HDFS') ? 'host_components/metrics/dfs/namenode/ClusterId,host_components/metrics/dfs/FSNamesystem/HAState,' : '') +
'<metrics>Hosts/total_mem<hostDetailsParams><stackVersions>&minimal_response=true',
hostDetailsParams = ',Hosts/os_arch,Hosts/os_type,metrics/cpu/cpu_system,metrics/cpu/cpu_user,metrics/memory/mem_total,metrics/memory/mem_free',
stackVersionInfo = ',stack_versions/HostStackVersions,' +
diff --git a/ambari-web/app/controllers/main/host/bulk_operations_controller.js b/ambari-web/app/controllers/main/host/bulk_operations_controller.js
index bb0cffd..90a089b 100644
--- a/ambari-web/app/controllers/main/host/bulk_operations_controller.js
+++ b/ambari-web/app/controllers/main/host/bulk_operations_controller.js
@@ -163,7 +163,7 @@ App.BulkOperationsController = Em.Controller.extend({
if (nn_hosts.length == 1) {
return App.router.get('mainHostDetailsController').checkNnLastCheckpointTime(request, nn_hosts[0]);
}
- if (nn_hosts.length == 2) {
+ if (nn_hosts.length > 1) {
// HA enabled
return App.router.get('mainServiceItemController').checkNnLastCheckpointTime(request);
}
@@ -224,8 +224,8 @@ App.BulkOperationsController = Em.Controller.extend({
}, hostName);
}
else {
- if (nn_count == 2 && isHDFSStarted) {
- // HA enabled
+ if (nn_count > 1 && isHDFSStarted) {
+ // HA or federation enabled
App.router.get('mainServiceItemController').checkNnLastCheckpointTime(function () {
batchUtils.restartHostComponents(hostComponents, Em.I18n.t('rollingrestart.context.allOnSelectedHosts'), "HOST");
});
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index ddf0a70..774d897 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -396,7 +396,9 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
self.getHdfsUser().done(function() {
var msg = Em.Object.create({
confirmMsg: Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld').format(App.nnCheckpointAgeAlertThreshold) +
- Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions').format(isNNCheckpointTooOld, self.get('hdfsUser')),
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.makeSure') +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions.singleHost.login').format(isNNCheckpointTooOld) +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions').format(self.get('hdfsUser')),
confirmButton: Em.I18n.t('common.next')
});
return App.showConfirmationFeedBackPopup(callback, msg);
diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js
index a4a8ca1..d60b50a 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -88,6 +88,10 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
isRecommendationInProgress: false,
+ nameNodesWithOldCheckpoints: [],
+
+ isNameNodeCheckpointUnavailable: false,
+
isClientsOnlyService: function() {
return App.get('services.clientOnly').contains(this.get('content.serviceName'));
}.property('content.serviceName'),
@@ -352,7 +356,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
this.checkNnLastCheckpointTime(() => App.showConfirmationFeedBackPopup((query, runMmOperation) => {
this.set('isPending', true);
this.startStopWithMmode(serviceHealth, query, runMmOperation, components, hosts, label);
- }, bodyMessage));
+ }, bodyMessage), label);
} else {
return App.showConfirmationFeedBackPopup((query, runMmOperation) => {
this.set('isPending', true);
@@ -365,23 +369,46 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
/**
* this function will be called from :1) stop HDFS 2) restart all for HDFS 3) restart all affected for HDFS
* @param callback - callback function to continue next operation
+ * @param [groupName] - id of HA namespace for enabled NameNode federation
*/
- checkNnLastCheckpointTime: function(callback) {
- var self = this;
- this.pullNnCheckPointTime().complete(function () {
- var isNNCheckpointTooOld = self.get('isNNCheckpointTooOld');
- self.set('isNNCheckpointTooOld', null);
- if (isNNCheckpointTooOld) {
+ checkNnLastCheckpointTime: function (callback, groupName) {
+ this.pullNnCheckPointTime(groupName).complete(() => {
+ const nameNodesWithOldCheckpoints = this.get('nameNodesWithOldCheckpoints').slice(),
+ isNameNodeCheckpointUnavailable = this.get('isNameNodeCheckpointUnavailable');
+ this.get('nameNodesWithOldCheckpoints').clear();
+ this.set('isNameNodeCheckpointUnavailable', false);
+ if (nameNodesWithOldCheckpoints.length) {
// too old
- self.getHdfsUser().done(function() {
- var msg = Em.Object.create({
- confirmMsg: Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld').format(App.nnCheckpointAgeAlertThreshold) +
- Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions').format(isNNCheckpointTooOld, self.get('hdfsUser')),
- confirmButton: Em.I18n.t('common.next')
- });
+ this.getHdfsUser().done(() => {
+ const maxAge = App.nnCheckpointAgeAlertThreshold,
+ hdfsUser = this.get('hdfsUser'),
+ confirmButton =Em.I18n.t('common.next');
+ let msg;
+ if (App.get('hasNameNodeFederation') && !groupName) {
+ const oldCheckpointNameSpacesList = nameNodesWithOldCheckpoints.map(nn => `<li>${nn.haNameSpace}</li>`),
+ nameSpacesString = `<ul>${oldCheckpointNameSpacesList.join('')}</ul>`,
+ hostNamesList = nameNodesWithOldCheckpoints.map(nn => `<b>${nn.hostName}</b>`).join(', ');
+ msg = Em.Object.create({
+ confirmMsg: Em.I18n.t('services.service.stop.HDFS.warningMsg.nameSpaces.checkPointTooOld').format(maxAge) +
+ nameSpacesString +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.makeSure') +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions.multipleHosts.login').format(hostNamesList) +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions').format(hdfsUser),
+ confirmButton
+ })
+ } else {
+ const hostName = nameNodesWithOldCheckpoints[0].hostName;
+ msg = Em.Object.create({
+ confirmMsg: Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld').format(maxAge) +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.makeSure') +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions.singleHost.login').format(hostName) +
+ Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions').format(hdfsUser),
+ confirmButton
+ })
+ }
return App.showConfirmationFeedBackPopup(callback, msg);
});
- } else if (isNNCheckpointTooOld == null) {
+ } else if (isNameNodeCheckpointUnavailable) {
// not available
return App.showConfirmationPopup(
callback, Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointNA'), null,
@@ -394,56 +421,80 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
});
},
- pullNnCheckPointTime: function () {
+ pullNnCheckPointTime: function (haNameSpace) {
return App.ajax.send({
name: 'common.service.hdfs.getNnCheckPointTime',
sender: this,
+ data: {
+ haNameSpace
+ },
success: 'parseNnCheckPointTime'
});
},
- parseNnCheckPointTime: function (data) {
- var nameNodesStatus = [];
- var lastCheckpointTime, hostName;
- if (data.host_components.length <= 1) {
- lastCheckpointTime = Em.get(data.host_components[0], 'metrics.dfs.FSNamesystem.LastCheckpointTime');
- hostName = Em.get(data.host_components[0], 'HostRoles.host_name');
+ parseNnCheckPointTime: function (data, opt, params) {
+ let nameNodesStatus = {},
+ nameNodesWithCheckpoints = [],
+ hostComponents = params.haNameSpace ?
+ data.host_components.filterProperty('metrics.dfs.namenode.ClusterId', params.haNameSpace) : data.host_components;
+ if (hostComponents.length <= 1) {
+ nameNodesWithCheckpoints.push({
+ lastCheckpointTime: Em.get(hostComponents[0], 'metrics.dfs.FSNamesystem.LastCheckpointTime'),
+ hostName: Em.get(hostComponents[0], 'HostRoles.host_name')
+ });
} else {
- // HA enabled
- data.host_components.forEach(function(namenode) {
- nameNodesStatus.pushObject( Em.Object.create({
+ // HA or federation enabled
+ const hostComponents = data.host_components;
+ hostComponents.forEach(namenode => {
+ const haNameSpace = Em.get(namenode, 'metrics.dfs.namenode.ClusterId'),
+ existingArray = nameNodesStatus[haNameSpace],
+ currentArray = existingArray || [];
+ if (!existingArray) {
+ nameNodesStatus[haNameSpace] = currentArray;
+ }
+ currentArray.pushObject(Em.Object.create({
LastCheckpointTime: Em.get(namenode, 'metrics.dfs.FSNamesystem.LastCheckpointTime'),
HAState: Em.get(namenode, 'metrics.dfs.FSNamesystem.HAState'),
hostName: Em.get(namenode, 'HostRoles.host_name')
}));
});
- if (nameNodesStatus.someProperty('HAState', 'active')) {
- if (nameNodesStatus.findProperty('HAState', 'active').get('LastCheckpointTime')) {
- lastCheckpointTime = nameNodesStatus.findProperty('HAState', 'active').get('LastCheckpointTime');
- hostName = nameNodesStatus.findProperty('HAState', 'active').get('hostName');
- } else if (nameNodesStatus.someProperty('LastCheckpointTime')) {
- lastCheckpointTime = nameNodesStatus.findProperty('LastCheckpointTime').get('LastCheckpointTime');
- hostName = nameNodesStatus.findProperty('LastCheckpointTime').get('hostName');
+ Object.keys(nameNodesStatus).forEach(key => {
+ const nameSpace = nameNodesStatus[key],
+ activeNameNode = nameSpace.findProperty('HAState', 'active'),
+ standbyNameNode = nameSpace.findProperty('HAState', 'standby');
+ if (activeNameNode) {
+ const lastActiveNameNodeCheckpointTime = activeNameNode.get('LastCheckpointTime'),
+ nameNodeWithCheckpoint = nameSpace.findProperty('LastCheckpointTime');
+ if (lastActiveNameNodeCheckpointTime) {
+ nameNodesWithCheckpoints.push({
+ lastCheckpointTime: lastActiveNameNodeCheckpointTime,
+ hostName: activeNameNode.get('hostName'),
+ haNameSpace: key
+ });
+ } else if (nameNodeWithCheckpoint) {
+ nameNodesWithCheckpoints.push({
+ lastCheckpointTime: nameNodeWithCheckpoint.get('LastCheckpointTime'),
+ hostName: nameNodeWithCheckpoint.get('hostName'),
+ haNameSpace: key
+ });
+ }
+ } else if (standbyNameNode) {
+ nameNodesWithCheckpoints.push({
+ lastCheckpointTime: standbyNameNode.get('LastCheckpointTime'),
+ hostName: standbyNameNode.get('hostName'),
+ haNameSpace: key
+ });
}
- } else if (nameNodesStatus.someProperty('HAState', 'standby')) {
- lastCheckpointTime = nameNodesStatus.findProperty('HAState', 'standby').get('LastCheckpointTime');
- hostName = nameNodesStatus.findProperty('HAState', 'standby').get('hostName')
- }
+ });
}
+ const timeCriteria = App.nnCheckpointAgeAlertThreshold, // time in hours to define how many hours ago is too old
+ timeAgo = (Math.round(App.dateTime() / 1000) - (timeCriteria * 3600)) * 1000,
+ nameNodesWithOldCheckpoints = nameNodesWithCheckpoints.filter(nameNode => nameNode.lastCheckpointTime <= timeAgo);
- if (!lastCheckpointTime) {
- this.set("isNNCheckpointTooOld", null);
- } else {
- var time_criteria = App.nnCheckpointAgeAlertThreshold; // time in hours to define how many hours ago is too old
- var time_ago = (Math.round(App.dateTime() / 1000) - (time_criteria * 3600)) *1000;
- if (lastCheckpointTime <= time_ago) {
- // too old, set the effected hostName
- this.set("isNNCheckpointTooOld", hostName);
- } else {
- // still young
- this.set("isNNCheckpointTooOld", false);
- }
- }
+ this.setProperties({
+ nameNodesWithOldCheckpoints,
+ isNameNodeCheckpointUnavailable: !nameNodesWithCheckpoints.length
+ });
},
/**
@@ -947,7 +998,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
return App.showConfirmationFeedBackPopup(function (query, runMmOperation) {
batchUtils.restartCertainServiceHostComponents(serviceName, components, hosts, label, query, runMmOperation);
}, bodyMessage);
- });
+ }, label);
} else {
App.showConfirmationFeedBackPopup(function (query, runMmOperation) {
batchUtils.restartCertainServiceHostComponents(serviceName, components, hosts, label, query, runMmOperation);
diff --git a/ambari-web/app/mappers/hosts_mapper.js b/ambari-web/app/mappers/hosts_mapper.js
index d3864b4..7f05561 100644
--- a/ambari-web/app/mappers/hosts_mapper.js
+++ b/ambari-web/app/mappers/hosts_mapper.js
@@ -67,7 +67,8 @@ App.hostsMapper = App.QuickDataMapper.create({
stale_configs: 'HostRoles.stale_configs',
host_name: 'host_name',
public_host_name: 'public_host_name',
- admin_state: 'HostRoles.desired_admin_state'
+ admin_state: 'HostRoles.desired_admin_state',
+ ha_name_space: 'metrics.dfs.namenode.ClusterId'
},
stackVersionConfig: {
id: 'HostStackVersions.id',
diff --git a/ambari-web/app/mappers/service_metrics_mapper.js b/ambari-web/app/mappers/service_metrics_mapper.js
index 661e064..4d319fc 100644
--- a/ambari-web/app/mappers/service_metrics_mapper.js
+++ b/ambari-web/app/mappers/service_metrics_mapper.js
@@ -44,6 +44,8 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
active_name_node_id: 'active_name_node_id',
standby_name_node_id: 'standby_name_node_id',
standby_name_node2_id: 'standby_name_node2_id',
+ active_name_nodes: 'active_name_nodes',
+ standby_name_nodes: 'standby_name_nodes',
journal_nodes: 'journal_nodes',
name_node_id: 'name_node_id',
sname_node_id: 'sname_node_id',
@@ -164,9 +166,8 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
stale_configs: 'HostRoles.stale_configs',
ha_status: 'HostRoles.ha_state',
display_name_advanced: 'display_name_advanced',
- admin_state: 'HostRoles.desired_admin_state'
- // TODO add mapping for namespace property
- // ha_name_space:
+ admin_state: 'HostRoles.desired_admin_state',
+ ha_name_space: 'metrics.dfs.namenode.ClusterId'
},
/**
@@ -349,7 +350,7 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
hostComponents.forEach(function (hostComponent) {
var service = services.findProperty('ServiceInfo.service_name', hostComponent.service_id);
if (hostComponent) {
- // set advanced nameNode display name for HA, Active NameNode or Standby NameNode
+ // set advanced nameNode display name for HA and Federation, Active NameNodes or Standby NameNodes
// this is useful on three places: 1) HDFS health status hover tooltip, 2) HDFS service summary 3) NameNode component on host detail page
if (hostComponent.component_name === 'NAMENODE' && !isSecondaryNamenode) {
var hdfs = this.hdfsMapper(service);
@@ -358,9 +359,9 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
var standbyNNText = Em.I18n.t('services.service.summary.nameNode.standby');
if (hdfs) {
// active_name_node_id format : NAMENODE_c6401.ambari.apache.org
- if (hdfs.active_name_node_id && hdfs.active_name_node_id.contains(hostName)) {
+ if (hdfs.active_name_nodes && hdfs.active_name_nodes.contains(`NAMENODE_${hostName}`)) {
hostComponent.display_name_advanced = activeNNText;
- } else if ((hdfs.standby_name_node_id && hdfs.standby_name_node_id.contains(hostName)) || ( hdfs.standby_name_node2_id && hdfs.standby_name_node2_id.contains(hostName))) {
+ } else if (hdfs.standby_name_nodes && hdfs.standby_name_nodes.contains(`NAMENODE_${hostName}`)) {
hostComponent.display_name_advanced = standbyNNText;
} else {
hostComponent.display_name_advanced = null;
@@ -418,20 +419,55 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
},
hdfsMapper: function (item) {
- var finalConfig = jQuery.extend({}, this.config);
+ let finalConfig = jQuery.extend({}, this.config);
// Change the JSON so that it is easy to map
- var hdfsConfig = this.hdfsConfig;
- var self = this;
- item.components.forEach(function (component) {
+ const hdfsConfig = this.hdfsConfig;
+ item.components.forEach(component => {
+ const hostComponents = component.host_components,
+ firstHostComponent = hostComponents[0];
if (this.isHostComponentPresent(component, 'NAMENODE')) {
//enabled HA
- if (component.host_components.length == 2) {
- var haState1 = Em.get(component.host_components[0], 'metrics.dfs.FSNamesystem.HAState');
- var haState2 = Em.get(component.host_components[1], 'metrics.dfs.FSNamesystem.HAState');
- var active_name_node = [];
- var standby_name_nodes = [];
- var namenodeName1 = component.host_components[0].HostRoles.host_name;
- var namenodeName2 = component.host_components[1].HostRoles.host_name;
+ if (hostComponents.length > 1) {
+ let nameSpacesWithActiveNameNodes = [],
+ unknownNameNodes = [];
+ item.active_name_nodes = [];
+ item.standby_name_nodes = [];
+ hostComponents.forEach(hc => {
+ const haState = Em.get(hc, 'metrics.dfs.FSNamesystem.HAState'),
+ hostName = Em.get(hc, 'HostRoles.host_name'),
+ haNameSpace = Em.get(hc, 'metrics.dfs.namenode.ClusterId'),
+ id = `NAMENODE_${hostName}`;
+ switch (haState) {
+ case 'active':
+ nameSpacesWithActiveNameNodes.push(haNameSpace);
+ item.active_name_nodes.push(id);
+ break;
+ case 'standby':
+ item.standby_name_nodes.push(id);
+ break;
+ default:
+ unknownNameNodes.push({
+ hostName,
+ haNameSpace
+ });
+ break;
+ }
+ });
+ unknownNameNodes.forEach(nameNode => {
+ if (nameSpacesWithActiveNameNodes.contains(nameNode.haNameSpace)) {
+ item.standby_name_nodes.push(`NAMENODE_${nameNode.hostName}`);
+ }
+ });
+ }
+
+ // TODO remove after implementing widgets changes
+ if (hostComponents.length === 2) {
+ const haState1 = Em.get(firstHostComponent, 'metrics.dfs.FSNamesystem.HAState'),
+ haState2 = Em.get(hostComponents[1], 'metrics.dfs.FSNamesystem.HAState'),
+ namenodeName1 = firstHostComponent.HostRoles.host_name,
+ namenodeName2 = hostComponents[1].HostRoles.host_name;
+ let active_name_node = [],
+ standby_name_nodes = [];
switch (haState1) {
case "active":
@@ -454,31 +490,32 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
item.standby_name_node2_id = null;
switch (active_name_node.length) {
case 1:
- item.active_name_node_id = 'NAMENODE' + '_' + active_name_node[0];
+ item.active_name_node_id = `NAMENODE_${active_name_node[0]}`;
break;
}
switch (standby_name_nodes.length) {
case 0:
if (active_name_node.length === 1) {
- var standbyNameNode = (active_name_node[0] === namenodeName1) ? namenodeName2 : namenodeName1;
- item.standby_name_node_id = 'NAMENODE' + '_' + standbyNameNode;
+ const standbyNameNode = (active_name_node[0] === namenodeName1) ? namenodeName2 : namenodeName1;
+ item.standby_name_node_id = `NAMENODE_${standbyNameNode}`;
}
break;
case 1:
- item.standby_name_node_id = 'NAMENODE' + '_' + standby_name_nodes[0];
+ item.standby_name_node_id = `NAMENODE_${standby_name_nodes[0]}`;
break;
case 2:
- item.standby_name_node_id = 'NAMENODE' + '_' + standby_name_nodes[0];
- item.standby_name_node2_id = 'NAMENODE' + '_' + standby_name_nodes[1];
+ item.standby_name_node_id = `NAMENODE_${standby_name_nodes[0]}`;
+ item.standby_name_node2_id = `NAMENODE_${standby_name_nodes[1]}`;
break;
}
var activeHostComponentIndex = haState2 == "active" ? 1 : 0;
- self.setActiveAsFirstHostComponent(component, activeHostComponentIndex);
+ this.setActiveAsFirstHostComponent(component, activeHostComponentIndex);
}
+
item.nameNodeComponent = component;
finalConfig = jQuery.extend(finalConfig, hdfsConfig);
// Get the live, dead & decommission nodes from string json
- if (component.host_components[0].metrics && component.host_components[0].metrics.dfs && component.host_components[0].metrics.dfs.namenode) {
+ if (firstHostComponent.metrics && firstHostComponent.metrics.dfs && firstHostComponent.metrics.dfs.namenode) {
item.metrics_not_available = false;
var decommissionNodesJson = App.parseJSON(component.host_components[0].metrics.dfs.namenode.DecomNodes);
var deadNodesJson = App.parseJSON(component.host_components[0].metrics.dfs.namenode.DeadNodes);
@@ -489,29 +526,26 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
item.decommission_data_nodes = [];
item.dead_data_nodes = [];
item.live_data_nodes = [];
- for (var host in decommissionNodesJson) {
- item.decommission_data_nodes.push('DATANODE' + '_' + host);
+ for (let host in decommissionNodesJson) {
+ item.decommission_data_nodes.push(`DATANODE_${host}`);
}
- for (var host in deadNodesJson) {
- item.dead_data_nodes.push('DATANODE' + '_' + host);
+ for (let host in deadNodesJson) {
+ item.dead_data_nodes.push(`DATANODE_${host}`);
}
- for (var host in liveNodesJson) {
- item.live_data_nodes.push('DATANODE' + '_' + host);
+ for (let host in liveNodesJson) {
+ item.live_data_nodes.push(`DATANODE_${host}`);
}
- item.name_node_id = "NAMENODE" + "_" + component.host_components[0].HostRoles.host_name;
+ item.name_node_id = `NAMENODE_${firstHostComponent.HostRoles.host_name}`;
}
if (this.isHostComponentPresent(component, "JOURNALNODE")) {
- item.journal_nodes = [];
- component.host_components.forEach(function (hc) {
- item.journal_nodes.push("JOURNALNODE" + "_" + hc.HostRoles.host_name);
- });
+ item.journal_nodes = hostComponents.map(hc => `JOURNALNODE_${hc.HostRoles.host_name}`);
}
if (this.isHostComponentPresent(component, "SECONDARY_NAMENODE")) {
- item.sname_node_id = "SECONDARY_NAMENODE" + "_" + component.host_components[0].HostRoles.host_name;
+ item.sname_node_id = `SECONDARY_NAMENODE_${firstHostComponent.HostRoles.host_name}`;
}
- }, this);
+ });
// Map
- var finalJson = this.parseIt(item, finalConfig);
+ let finalJson = this.parseIt(item, finalConfig);
finalJson.quick_links = [1, 2, 3, 4];
return finalJson;
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 1703d2d..17b5a7f 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -2340,15 +2340,17 @@ Em.I18n.translations = {
'services.service.restartCertain.warningMsg.turnOnMM': 'This will trigger alerts as components are restarted. To suppress alerts, turn on Maintenance Mode for {0} prior to running restart all',
'services.service.componentsInNameSpace': 'components in {0} namespace',
'services.service.stop.HDFS.warningMsg.checkPointNA': 'Could not determine the age of the last HDFS checkpoint. Please ensure that you have a recent checkpoint. Otherwise, the NameNode(s) can take a very long time to start up.',
+ 'services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions.singleHost.login': '<br><ol><li>Login to the NameNode host <b>{0}</b>.</li>',
+ 'services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions.multipleHosts.login': '<ol><li>Login to the NameNode hosts {0}.</li>',
'services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions':
- '<br><ol>' +
- '<li>Login to the NameNode host <b>{0}</b>.</li>' +
'<li>Put the NameNode in Safe Mode (read-only mode):' +
- '<div class="code-snippet">sudo su {1} -l -c \'hdfs dfsadmin -safemode enter\'</div></li>' +
+ '<div class="code-snippet">sudo su {0} -l -c \'hdfs dfsadmin -safemode enter\'</div></li>' +
'<li>Once in Safe Mode, create a Checkpoint:' +
- '<div class="code-snippet">sudo su {1} -l -c \'hdfs dfsadmin -saveNamespace\'</div></li>' +
+ '<div class="code-snippet">sudo su {0} -l -c \'hdfs dfsadmin -saveNamespace\'</div></li>' +
'</ol>',
- 'services.service.stop.HDFS.warningMsg.checkPointTooOld': 'The last HDFS checkpoint is older than {0} hours. Make sure that you have taken a checkpoint before proceeding. Otherwise, the NameNode(s) can take a very long time to start up.',
+ 'services.service.stop.HDFS.warningMsg.checkPointTooOld': 'The last HDFS checkpoint is older than {0} hours. ',
+ 'services.service.stop.HDFS.warningMsg.checkPointTooOld.makeSure': 'Make sure that you have taken a checkpoint before proceeding. Otherwise, the NameNode(s) can take a very long time to start up.',
+ 'services.service.stop.HDFS.warningMsg.nameSpaces.checkPointTooOld': 'The last HDFS checkpoint is older than {0} hours for the following namespaces:',
'services.service.config_groups_popup.header':'Manage {0} Configuration Groups',
'services.service.config_groups_popup.notice':'You can apply different sets of {{serviceName}} configurations to groups of hosts by managing {{serviceName}} Configuration Groups and their host membership. Hosts belonging to a {{serviceName}} Configuration Group have the same set of configurations for {{serviceName}}. Each host belongs to one {{serviceName}} Configuration Group.',
'services.service.config_groups_popup.rename':'Rename',
diff --git a/ambari-web/app/models/host_component.js b/ambari-web/app/models/host_component.js
index 7b60a27..42fcae1 100644
--- a/ambari-web/app/models/host_component.js
+++ b/ambari-web/app/models/host_component.js
@@ -572,7 +572,8 @@ App.HostComponentActionMap = {
components: components || group.components,
serviceName
},
- disabled: false
+ disabled: false,
+ tooltip: group.title
};
});
return [allItem, ...groupItems];
diff --git a/ambari-web/app/models/service/hdfs.js b/ambari-web/app/models/service/hdfs.js
index fa279f9..08e160b 100644
--- a/ambari-web/app/models/service/hdfs.js
+++ b/ambari-web/app/models/service/hdfs.js
@@ -21,9 +21,18 @@ App.HDFSService = App.Service.extend({
version: DS.attr('string'),
nameNode: DS.belongsTo('App.HostComponent'),
snameNode: DS.belongsTo('App.HostComponent'),
+
+ // TODO remove after implementing widgets changes
activeNameNode: DS.belongsTo('App.HostComponent'),
standbyNameNode: DS.belongsTo('App.HostComponent'),
standbyNameNode2: DS.belongsTo('App.HostComponent'),
+
+ activeNameNodes: DS.hasMany('App.HostComponent', {
+ defaultValue: []
+ }),
+ standbyNameNodes: DS.hasMany('App.HostComponent', {
+ defaultValue: []
+ }),
isNnHaEnabled: function() {
return !this.get('snameNode') && this.get('hostComponents').filterProperty('componentName', 'NAMENODE').length > 1;
}.property('snameNode','hostComponents'),
@@ -75,7 +84,7 @@ App.HDFSService = App.Service.extend({
}
});
return result;
- }.property('hostComponents')
+ }.property('hostComponents.length')
});
App.HDFSService.FIXTURES = [];
diff --git a/ambari-web/app/styles/alerts.less b/ambari-web/app/styles/alerts.less
index a1d3468..efaf25d 100644
--- a/ambari-web/app/styles/alerts.less
+++ b/ambari-web/app/styles/alerts.less
@@ -196,10 +196,8 @@
}
.alert-text {
- overflow: hidden;
+ .ellipsis-overflow-nowrap;
float: left;
- text-overflow: ellipsis;
- white-space: nowrap;
width: 100%;
}
@@ -310,10 +308,8 @@
}
.alert-text {
- overflow: hidden;
+ .ellipsis-overflow-nowrap;
float: left;
- text-overflow: ellipsis;
- white-space: nowrap;
width: 100%;
}
}
@@ -514,19 +510,15 @@
}
.instance-text {
+ .ellipsis-overflow-nowrap;
font-size: 0.8em;
width: 95%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
}
.definition-latest-text {
+ .ellipsis-overflow-nowrap;
font-size: 0.8em;
width: 95%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
}
.alerts-popup-wrap {
@@ -537,9 +529,8 @@
padding: 10px 5px;
}
.trim_hostname {
+ .ellipsis-overflow;
display: block;
- overflow: hidden;
- text-overflow: ellipsis;
}
}
}
@@ -652,14 +643,11 @@
font-size: 14px;
font-weight: bold;
margin-bottom: 5px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+ .ellipsis-overflow-nowrap;
}
.description-text {
font-size: 12px;
- overflow: hidden;
- text-overflow: ellipsis;
+ .ellipsis-overflow;
}
}
}
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 7d7c268..27083a0 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -868,6 +868,9 @@ a:focus {
display: inline-block;
}
}
+ .master-group-title {
+ .ellipsis-overflow-nowrap;
+ }
}
.faintText {
@@ -1573,9 +1576,7 @@ ul.inline li {
}
.rack-id {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+ .ellipsis-overflow-nowrap;
}
.advanced-header-table {
diff --git a/ambari-web/app/styles/common.less b/ambari-web/app/styles/common.less
index 8dfdf69..810aefb 100644
--- a/ambari-web/app/styles/common.less
+++ b/ambari-web/app/styles/common.less
@@ -230,3 +230,13 @@
color: white;
}
}
+
+.ellipsis-overflow {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.ellipsis-overflow-nowrap {
+ .ellipsis-overflow;
+ white-space: nowrap;
+}
diff --git a/ambari-web/app/styles/enhanced_service_dashboard.less b/ambari-web/app/styles/enhanced_service_dashboard.less
index bb59a8b..a930788 100644
--- a/ambari-web/app/styles/enhanced_service_dashboard.less
+++ b/ambari-web/app/styles/enhanced_service_dashboard.less
@@ -101,14 +101,13 @@
margin: 55px auto;
}
.title {
+ .ellipsis-overflow;
padding: 4px 0 0 8px;
font-size: 14px;
color: #666666;
line-height: 17px;
text-align: left;
height: 40px;
- overflow: hidden;
- text-overflow: ellipsis;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: block;
@@ -123,11 +122,10 @@
.template-widget {
.frame;
.content {
+ .ellipsis-overflow;
padding-top: 21px;
height: 75px;
line-height: 36px;
- overflow: hidden;
- text-overflow: ellipsis;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: block;
@@ -137,11 +135,10 @@
.number-widget {
.frame;
.content {
+ .ellipsis-overflow;
padding-top: 30px;
height: 50px;
box-sizing: content-box;
- overflow: hidden;
- text-overflow: ellipsis;
}
}
.graph-widget {
@@ -368,16 +365,13 @@
}
.label-description {
.label-text {
+ .ellipsis-overflow-nowrap;
font-weight: bold;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
}
.description-text {
+ .ellipsis-overflow;
font-size: 12px;
color: #808080;
- overflow: hidden;
- text-overflow: ellipsis;
}
}
}
@@ -620,11 +614,9 @@
}
.label-description {
.label-text {
+ .ellipsis-overflow-nowrap;
display: inline-block;
font-weight: bold;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
}
.is-shared-icon {
display: inline-block;
diff --git a/ambari-web/app/styles/hosts.less b/ambari-web/app/styles/hosts.less
index 0909a3d..6cfa33c 100644
--- a/ambari-web/app/styles/hosts.less
+++ b/ambari-web/app/styles/hosts.less
@@ -188,12 +188,10 @@
white-space: nowrap;
}
td.name .trim_hostname{
+ .ellipsis-overflow-nowrap;
display: block;
float: left;
width: 86%!important;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
}
td.health label {
padding-top: 3px;
diff --git a/ambari-web/app/styles/stack_versions.less b/ambari-web/app/styles/stack_versions.less
index f47e3fc..2311acd 100644
--- a/ambari-web/app/styles/stack_versions.less
+++ b/ambari-web/app/styles/stack_versions.less
@@ -814,10 +814,8 @@
width: 14%;
}
.widest-column{
+ .ellipsis-overflow-nowrap;
width: 20%;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
}
.accordion-group {
border-right: none;
diff --git a/ambari-web/app/styles/visualsearch.less b/ambari-web/app/styles/visualsearch.less
index f07d319..16c3377 100644
--- a/ambari-web/app/styles/visualsearch.less
+++ b/ambari-web/app/styles/visualsearch.less
@@ -57,9 +57,7 @@
width: auto !important;
margin-top: 15px;
.ui-menu-item a {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+ .ellipsis-overflow-nowrap;
background: none;
border: none;
padding: 3px 10px 5px 5px;
diff --git a/ambari-web/app/styles/wizard.less b/ambari-web/app/styles/wizard.less
index 4d4eeaf..ba22fad 100644
--- a/ambari-web/app/styles/wizard.less
+++ b/ambari-web/app/styles/wizard.less
@@ -200,12 +200,10 @@
max-width: 290px;
}
td.host .trim_hostname {
+ .ellipsis-overflow-nowrap;
max-width: 97% !important;
display: block;
- overflow: hidden;
- text-overflow: ellipsis;
float:left;
- white-space: nowrap;
}
#display-action {
visibility:visible;
@@ -254,12 +252,10 @@
white-space: nowrap;
}
.trim_hostname {
+ .ellipsis-overflow-nowrap;
max-width: 180px;
float:left;
- white-space: nowrap;
display: block;
- overflow: hidden;
- text-overflow: ellipsis;
}
.checkbox {
margin: 0;
@@ -375,12 +371,10 @@
max-width: 290px;
}
td.host .trim_hostname {
+ .ellipsis-overflow-nowrap;
max-width: 97% !important;
display: block;
- overflow: hidden;
- text-overflow: ellipsis;
float:left;
- white-space: nowrap;
}
.progress-wrapper {
width: 73%;
@@ -505,11 +499,10 @@
text-align: left;
padding: 10px;
.selected-item {
+ .ellipsis-overflow;
width: 95%;
margin-right: 5px;
float: left;
- overflow: hidden;
- text-overflow: ellipsis;
}
}
}
diff --git a/ambari-web/app/templates/main/service/info/summary.hbs b/ambari-web/app/templates/main/service/info/summary.hbs
index 5f6219a..4b33bb8 100644
--- a/ambari-web/app/templates/main/service/info/summary.hbs
+++ b/ambari-web/app/templates/main/service/info/summary.hbs
@@ -46,16 +46,6 @@
{{/isAuthorized}}
{{/if}}
-{{#if view.hasMultipleMasterGroups}}
- <ul class="nav nav-tabs">
- {{#each group in view.mastersObj}}
- <li {{bindAttr class="group.isActive:active"}}>
- <a href="#" {{action setActiveComponentGroup group.name target="view"}}>{{group.title}}</a>
- </li>
- {{/each}}
- </ul>
-{{/if}}
-
<div class="service-block">
<div class="summary-links-block">
<div class="panel panel-default summary-block">
@@ -101,7 +91,10 @@
<!--there are multiple masters eg, HBase multiple masters or HDFS HA enabled-->
{{#each group in view.quickLinksArray}}
{{#if group.title}}
- <h5>{{group.title}}</h5>
+ <h5 class="ellipsis-overflow-nowrap"
+ {{bindAttr data-title="group.title" rel="view.tooltipAttribute"}}>
+ {{group.title}}
+ </h5>
{{/if}}
{{#each quickLinks in group.links}}
<a href="javascript:void(null)">{{quickLinks.publicHostNameLabel}} </a>
diff --git a/ambari-web/app/templates/main/service/info/summary/master_components.hbs b/ambari-web/app/templates/main/service/info/summary/master_components.hbs
index 9d2f2fd..6ca36c1 100644
--- a/ambari-web/app/templates/main/service/info/summary/master_components.hbs
+++ b/ambari-web/app/templates/main/service/info/summary/master_components.hbs
@@ -16,45 +16,45 @@
* limitations under the License.
}}
-{{#if view.activeMastersComp.length}}
- {{#each group in view.activeMastersComp}}
- {{#if group.components.length}}
- <div class="col-md-12">
- <div class="col-md-2">
- {{#if group.title}}
+{{#each group in view.mastersComp}}
+ {{#if group.components.length}}
+ <div class="col-md-12">
+ <div class="col-md-2">
+ {{#if group.title}}
+ <div class="master-group-title" rel="MasterGroupTitleTooltip" {{bindAttr data-title="group.title"}}>
{{group.title}}
- {{else}}
- {{t dashboard.services.hdfs.summary.components}}
- {{/if}}
- </div>
- <div class="col-md-10">
- {{#each comp in group.components}}
- <div {{bindAttr class="comp.isSubComponent:component-small :component :col-md-3 comp.componentName :row"}}>
- <div {{bindAttr class=":summary-value comp.summaryValueClassName"}}>
+ </div>
+ {{else}}
+ {{t dashboard.services.hdfs.summary.components}}
+ {{/if}}
+ </div>
+ <div class="col-md-10">
+ {{#each comp in group.components}}
+ <div {{bindAttr class="comp.isSubComponent:component-small :component :col-md-3 comp.componentName :row"}}>
+ <div {{bindAttr class=":summary-value comp.summaryValueClassName"}}>
<span rel='SummaryComponentHealthTooltip'
{{bindAttr class="comp.statusClass comp.statusIconClass" data-original-title="comp.passiveTooltip"}}></span>
- <span class="main-info">{{comp.componentTextStatus}}</span>
- {{#if comp.alertsCount}}
- <span {{action "showServiceAlertsPopup" comp target="controller"}}
- {{bindAttr class=":label comp.hasCriticalAlerts:alerts-crit-count:alerts-warn-count"}}>
- {{comp.alertsCount}}
- </span>
+ <span class="main-info">{{comp.componentTextStatus}}</span>
+ {{#if comp.alertsCount}}
+ <span {{action "showServiceAlertsPopup" comp target="controller"}}
+ {{bindAttr class=":label comp.hasCriticalAlerts:alerts-crit-count:alerts-warn-count"}}>
+ {{comp.alertsCount}}
+ </span>
+ {{/if}}
+ </div>
+ <div {{bindAttr class=":summary-label comp.summaryLabelClassName"}}>
+ <a href="#" {{action showDetails comp.host}} data-original-title="{{unbound comp.publicHostName}}"
+ rel="UsageTooltip">
+ {{#if comp.displayNameAdvanced}}
+ {{comp.displayNameAdvanced}}
+ {{else}}
+ {{comp.displayName}}
{{/if}}
- </div>
- <div {{bindAttr class=":summary-label comp.summaryLabelClassName"}}>
- <a href="#" {{action showDetails comp.host}} data-original-title="{{unbound comp.publicHostName}}"
- rel="UsageTooltip">
- {{#if comp.displayNameAdvanced}}
- {{comp.displayNameAdvanced}}
- {{else}}
- {{comp.displayName}}
- {{/if}}
- </a>
- </div>
+ </a>
</div>
- {{/each}}
- </div>
+ </div>
+ {{/each}}
</div>
- {{/if}}
- {{/each}}
-{{/if}}
+ </div>
+ {{/if}}
+{{/each}}
diff --git a/ambari-web/app/templates/main/service/item.hbs b/ambari-web/app/templates/main/service/item.hbs
index ad616e8..a7d9e8d 100644
--- a/ambari-web/app/templates/main/service/item.hbs
+++ b/ambari-web/app/templates/main/service/item.hbs
@@ -37,7 +37,8 @@
{{#each option in view.maintenance}}
{{#unless option.isHidden}}
<li {{bindAttr class="option.disabled option.hasSubmenu:dropdown-submenu option.hasSubmenu:submenu-left"}}>
- <a {{action "doAction" option target="controller" href=true}} {{bindAttr data-title="option.tooltip"}} rel="HealthTooltip">
+ <a {{action "doAction" option target="controller" href=true}}
+ {{bindAttr data-title="option.tooltip" rel="view.tooltipAttribute"}}>
<i {{bindAttr class="option.cssClass"}}></i>
{{option.label}}
</a>
@@ -46,7 +47,10 @@
<ul class="dropdown-menu">
{{#each item in option.submenuOptions}}
<li>
- <a {{action "doAction" item target="controller" href=true}}>{{item.context.label}}</a>
+ <a class="ellipsis-overflow" {{action "doAction" item target="controller" href=true}}
+ {{bindAttr data-title="item.tooltip" rel="view.tooltipAttribute"}}>
+ {{item.context.label}}
+ </a>
</li>
{{/each}}
</ul>
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index a14b8eb..6c73a84 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -93,7 +93,7 @@ var urls = {
},
'common.service.hdfs.getNnCheckPointTime': {
- 'real': '/clusters/{clusterName}/services/HDFS/components/NAMENODE?fields=host_components/metrics/dfs/FSNamesystem/HAState,host_components/metrics/dfs/FSNamesystem/LastCheckpointTime',
+ 'real': '/clusters/{clusterName}/services/HDFS/components/NAMENODE?fields=host_components/metrics/dfs/FSNamesystem/HAState,host_components/metrics/dfs/FSNamesystem/LastCheckpointTime,host_components/metrics/dfs/namenode/ClusterId',
'mock': ''
},
diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js
index d2a7ae1..691fda4 100644
--- a/ambari-web/app/views/common/chart/linear_time.js
+++ b/ambari-web/app/views/common/chart/linear_time.js
@@ -367,6 +367,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
YARNService = App.YARNService.find().objectAt(0),
resourceManager = YARNService ? YARNService.get('resourceManager.hostName') : "";
if (HDFSService) {
+ // TODO rewrite considering federation case and using activeNameNodes array
nameNodeName = (HDFSService.get('activeNameNode')) ? HDFSService.get('activeNameNode.hostName') : HDFSService.get('nameNode.hostName');
}
if (this.get('currentTimeIndex') === 8 && !Em.isNone(this.get('customStartTime')) && !Em.isNone(this.get('customEndTime'))) {
diff --git a/ambari-web/app/views/common/quick_view_link_view.js b/ambari-web/app/views/common/quick_view_link_view.js
index 0a2f3cf..2e4b61a 100644
--- a/ambari-web/app/views/common/quick_view_link_view.js
+++ b/ambari-web/app/views/common/quick_view_link_view.js
@@ -81,6 +81,8 @@ App.QuickLinksView = Em.View.extend({
masterGroups: [],
+ tooltipAttribute: 'quick-links-title-tooltip',
+
/**
* @type {object}
*/
@@ -618,20 +620,18 @@ App.QuickLinksView = Em.View.extend({
* @method hostForQuickLink
*/
processHdfsHosts: function (hosts) {
- return hosts.map(function (host) {
- if (host.hostName === Em.get(this, 'content.activeNameNode.hostName')) {
+ return hosts.map(host => {
+ const {hostName} = host,
+ isActiveNameNode = Em.get(this, 'content.activeNameNodes').someProperty('hostName', hostName),
+ isStandbyNameNode = Em.get(this, 'content.standbyNameNodes').someProperty('hostName', hostName);
+ if (isActiveNameNode) {
host.status = Em.I18n.t('quick.links.label.active');
}
- else
- if (host.hostName === Em.get(this, 'content.standbyNameNode.hostName')) {
- host.status = Em.I18n.t('quick.links.label.standby');
- }
- else
- if (host.hostName === Em.get(this, 'content.standbyNameNode2.hostName')) {
- host.status = Em.I18n.t('quick.links.label.standby');
- }
+ if (isStandbyNameNode) {
+ host.status = Em.I18n.t('quick.links.label.standby');
+ }
return host;
- }, this);
+ });
},
/**
@@ -889,5 +889,13 @@ App.QuickLinksView = Em.View.extend({
} else {
return propertyValue;
}
- }
+ },
+
+ setTooltip: function () {
+ Em.run.next(() => {
+ if (this.get('showQuickLinks') && this.get('isLoaded') && this.get('quickLinksArray.length')) {
+ App.tooltip($(`[rel="${this.get('tooltipAttribute')}"]`));
+ }
+ });
+ }.observes('showQuickLinks', 'isLoaded', 'quickLinksArray.length')
});
diff --git a/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
index 900a900..e4af3cd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
@@ -35,6 +35,8 @@ App.HDFSLinksView = App.LinkDashboardWidgetView.extend({
isHAEnabled: Em.computed.not('model.snameNode'),
+ // TODO rewrite considering federation case and using activeNameNodes and standbyNameNodes arrays
+
isActiveNNValid: Em.computed.bool('model.activeNameNode'),
isStandbyNNValid: Em.computed.bool('model.standbyNameNode'),
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
index d6a3ebd..2916cd3 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
@@ -35,6 +35,7 @@ App.NameNodeCpuPieChartView = App.PieChartDashboardWidgetView.extend({
intervalId;
App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isServiceContentFullyLoaded').done(function () {
if (App.get('isHaEnabled')) {
+ // TODO rewrite considering federation case and using activeNameNodes array
self.set('nnHostName', self.get('model.activeNameNode.hostName'));
} else {
self.set('nnHostName', self.get('model.nameNode.hostName'));
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
index f7178cc..f0fe97f 100644
--- 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
@@ -29,6 +29,7 @@ App.DataNodeComponentView = App.HostComponentView.extend(App.Decommissionable, {
getDNDecommissionStatus: function () {
// always get datanode decommission status from active namenode (if NN HA enabled)
var hdfs = App.HDFSService.find().objectAt(0);
+ // TODO rewrite considering federation case and using activeNameNodes array
var activeNNHostName = (!hdfs.get('snameNode') && hdfs.get('activeNameNode')) ? hdfs.get('activeNameNode.hostName') : hdfs.get('nameNode.hostName');
return App.ajax.send({
name: 'host.host_component.decommission_status_datanode',
diff --git a/ambari-web/app/views/main/service/info/components_list_view.js b/ambari-web/app/views/main/service/info/components_list_view.js
index d14e8e4..524be23 100644
--- a/ambari-web/app/views/main/service/info/components_list_view.js
+++ b/ambari-web/app/views/main/service/info/components_list_view.js
@@ -27,19 +27,13 @@ App.SummaryMasterComponentsView = Em.View.extend({
}
],
- activeMastersComp: function () {
- const mastersComp = this.get('mastersComp'),
- activeGroup = mastersComp.findProperty('isActive');
- return activeGroup ? [activeGroup] : mastersComp;
- }.property('mastersComp.length', 'mastersComp.@each.isActive', 'mastersComp.@each.components.length'),
-
mastersCompWillChange: function() {
- Em.run.next(() => this.removeTooltips());
- }.observesBefore('mastersComp.length', 'mastersComp.@each.components.length'),
+ Em.run.next(this.removeTooltips);
+ }.observesBefore('mastersComp.length', 'mastersComp.@each.components'),
mastersCompDidChange: function() {
- Em.run.next(() => this.attachTooltip());
- }.observes('mastersComp.length', 'mastersComp.@each.components.length'),
+ Em.run.next(this.attachTooltip);
+ }.observes('mastersComp.length', 'mastersComp.@each.components'),
removeTooltips: function() {
$('.tooltip').remove();
@@ -60,7 +54,7 @@ App.SummaryMasterComponentsView = Em.View.extend({
});
App.SummaryMasterComponentsView.reopenClass({
- tooltipsSelector: '[rel=SummaryComponentHealthTooltip], [rel=UsageTooltip]'
+ tooltipsSelector: '[rel=SummaryComponentHealthTooltip], [rel=UsageTooltip], [rel=MasterGroupTitleTooltip]'
});
App.SummaryClientComponentsView = Em.View.extend({
diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js
index e35ca40..193f96d 100644
--- a/ambari-web/app/views/main/service/info/summary.js
+++ b/ambari-web/app/views/main/service/info/summary.js
@@ -29,7 +29,7 @@ App.MainServiceInfoSummaryView = Em.View.extend({
/**
* Contain array with list of groups of master components from <code>App.Service.hostComponets</code> which are
* <code>App.HostComponent</code> models.
- * @type {{title: String, isActive: Boolean, hosts: String[], components: App.HostComponent[]}[]}
+ * @type {{title: String, hosts: String[], components: App.HostComponent[]}[]}
*/
mastersObj: [
{
@@ -423,11 +423,6 @@ App.MainServiceInfoSummaryView = Em.View.extend({
hasMultipleMasterGroups: Em.computed.gt('mastersObj.length', 1),
- activeMasterComponentGroup: function () {
- const activeGroup = this.get('mastersObj').findProperty('isActive');
- return activeGroup ? activeGroup.title : '';
- }.property('mastersObj.@each.isActive'),
-
getGroupedMasterComponents: function (components) {
switch (this.get('serviceName')) {
case 'HDFS':
@@ -447,7 +442,6 @@ App.MainServiceInfoSummaryView = Em.View.extend({
if (!existingGroup) {
groups.push(currentGroup);
Em.setProperties(currentGroup, {
- isActive: name === this.get('activeMasterComponentGroup'),
components: []
});
}
@@ -479,10 +473,5 @@ App.MainServiceInfoSummaryView = Em.View.extend({
}
];
}
- },
-
- setActiveComponentGroup: function (event) {
- const groupName = event.context;
- this.get('mastersObj').forEach(group => Em.set(group, 'isActive', group.name === groupName));
}
});
diff --git a/ambari-web/app/views/main/service/item.js b/ambari-web/app/views/main/service/item.js
index 9240af8..1d4e5a6 100644
--- a/ambari-web/app/views/main/service/item.js
+++ b/ambari-web/app/views/main/service/item.js
@@ -110,6 +110,8 @@ App.MainServiceItemView = Em.View.extend({
isMaintenanceSet: false,
+ tooltipAttribute: 'service-actions-tooltip',
+
observeMaintenance: function() {
if (!this.get('isMaintenanceSet') && this.get('controller.isServicesInfoLoaded') && this.get('controller.isServiceConfigsLoaded')) {
this.observeMaintenanceOnce();
@@ -329,6 +331,7 @@ App.MainServiceItemView = Em.View.extend({
this.set('maintenance', options);
}
this.set('isMaintenanceSet', true);
+ App.tooltip($(`[rel="${this.get('tooltipAttribute')}"]`));
},
clearIsMaintenanceSet: function () {
diff --git a/ambari-web/test/controllers/global/update_controller_test.js b/ambari-web/test/controllers/global/update_controller_test.js
index a812353..6165af9 100644
--- a/ambari-web/test/controllers/global/update_controller_test.js
+++ b/ambari-web/test/controllers/global/update_controller_test.js
@@ -108,7 +108,7 @@ describe('App.UpdateController', function () {
}
}
],
- result: ['metrics/1']
+ result: ['metrics/1', 'host_components/metrics/dfs/namenode/ClusterId']
},
{
title: 'FLUME service',
diff --git a/ambari-web/test/controllers/main/service/item_test.js b/ambari-web/test/controllers/main/service/item_test.js
index 2ac35a2..250b03a 100644
--- a/ambari-web/test/controllers/main/service/item_test.js
+++ b/ambari-web/test/controllers/main/service/item_test.js
@@ -619,7 +619,7 @@ describe('App.MainServiceItemController', function () {
}
]
},
- result: false
+ result: 0
},
{
m: "NameNode has JMX data, the last checkpoint time is > 12 hours ago",
@@ -649,7 +649,7 @@ describe('App.MainServiceItemController', function () {
}
]
},
- result: "c6401.ambari.apache.org"
+ result: 1
},
{
m: "NameNode has no JMX data available",
@@ -678,7 +678,7 @@ describe('App.MainServiceItemController', function () {
}
]
},
- result: null
+ result: 0
},
{
m: "HA enabled, both active and standby NN has JMX data normally.",
@@ -724,7 +724,7 @@ describe('App.MainServiceItemController', function () {
}
]
},
- result: false
+ result: 0
},
{
m: "HA enabled, both NamoNodes are standby NN",
@@ -770,7 +770,7 @@ describe('App.MainServiceItemController', function () {
}
]
},
- result: false
+ result: 0
},
{
m: "HA enabled, active NN has no JMX data, use the standby's data",
@@ -815,10 +815,10 @@ describe('App.MainServiceItemController', function () {
}
]
},
- result: false
+ result: 0
},
{
- m: "HA enabled, both NamoNodes no JMX data",
+ m: "HA enabled, both NameNodes no JMX data",
data:
{"href" : "",
"ServiceComponentInfo" : {
@@ -859,7 +859,7 @@ describe('App.MainServiceItemController', function () {
}
]
},
- result: null
+ result: 0
}
];
@@ -874,8 +874,8 @@ describe('App.MainServiceItemController', function () {
tests.forEach(function (test) {
it(test.m, function () {
var mainServiceItemController = App.MainServiceItemController.create({isNNCheckpointTooOld: null});
- mainServiceItemController.parseNnCheckPointTime(test.data);
- expect(mainServiceItemController.get('isNNCheckpointTooOld')).to.equal(test.result);
+ mainServiceItemController.parseNnCheckPointTime(test.data, null, {});
+ expect(mainServiceItemController.get('nameNodesWithOldCheckpoints.length')).to.equal(test.result);
});
});
});
diff --git a/ambari-web/test/views/common/quick_link_view_test.js b/ambari-web/test/views/common/quick_link_view_test.js
index 3100b17..8f280b6 100644
--- a/ambari-web/test/views/common/quick_link_view_test.js
+++ b/ambari-web/test/views/common/quick_link_view_test.js
@@ -376,24 +376,17 @@ describe('App.QuickViewLinks', function () {
describe("#processHdfsHosts()", function () {
beforeEach(function () {
- quickViewLinks.set('content.activeNameNode', null);
- quickViewLinks.set('content.standbyNameNode', null);
- quickViewLinks.set('content.standbyNameNode2', null);
+ quickViewLinks.set('content.activeNameNodes', []);
+ quickViewLinks.set('content.standbyNameNodes', []);
});
it("active namenode host", function () {
- quickViewLinks.set('content.activeNameNode', Em.Object.create({hostName: 'host1'}));
+ quickViewLinks.get('content.activeNameNodes').pushObject(Em.Object.create({hostName: 'host1'}));
var host = {hostName: 'host1'};
quickViewLinks.processHdfsHosts([host]);
expect(host.status).to.equal(Em.I18n.t('quick.links.label.active'));
});
it("standby namenode host", function () {
- quickViewLinks.set('content.standbyNameNode', Em.Object.create({hostName: 'host1'}));
- var host = {hostName: 'host1'};
- quickViewLinks.processHdfsHosts([host]);
- expect(host.status).to.equal(Em.I18n.t('quick.links.label.standby'));
- });
- it("second standby namenode host", function () {
- quickViewLinks.set('content.standbyNameNode2', Em.Object.create({hostName: 'host1'}));
+ quickViewLinks.get('content.standbyNameNodes').pushObject(Em.Object.create({hostName: 'host1'}));
var host = {hostName: 'host1'};
quickViewLinks.processHdfsHosts([host]);
expect(host.status).to.equal(Em.I18n.t('quick.links.label.standby'));
--
To stop receiving notification emails like this one, please contact
ababiichuk@apache.org.