/**
* 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.
*/
// Application bootstrapper
require('utils/ember_reopen');
var stringUtils = require('utils/string_utils');
module.exports = Em.Application.create({
name: 'Ambari Web',
rootElement: '#wrapper',
store: DS.Store.create({
revision: 4,
adapter: DS.FixtureAdapter.create({
simulateRemoteResponse: false
})
}),
isAdmin: false,
/**
* return url prefix with number value of version of HDP stack
*/
stackVersionURL:function(){
var stackVersion = this.get('currentStackVersion') || this.get('defaultStackVersion');
if(stackVersion.indexOf('HDPLocal') !== -1){
return '/stacks/HDPLocal/version/' + stackVersion.replace(/HDPLocal-/g, '');
}
return '/stacks/HDP/version/' + stackVersion.replace(/HDP-/g, '');
}.property('currentStackVersion'),
/**
* return url prefix with number value of version of HDP stack
*/
stack2VersionURL:function(){
var stackVersion = this.get('currentStackVersion') || this.get('defaultStackVersion');
if(stackVersion.indexOf('HDPLocal') !== -1){
return '/stacks2/HDPLocal/versions/' + stackVersion.replace(/HDPLocal-/g, '');
}
return '/stacks2/HDP/versions/' + stackVersion.replace(/HDP-/g, '');
}.property('currentStackVersion'),
falconServerURL: function () {
var falconService = this.Service.find().findProperty('serviceName', 'FALCON');
if (falconService) {
return falconService.get('hostComponents').findProperty('componentName', 'FALCON_SERVER').get('host.hostName');
}
return '';
}.property().volatile(),
clusterName: null,
clockDistance:null, // server clock - client clock
currentStackVersion: '',
currentStackVersionNumber: function(){
return this.get('currentStackVersion').replace(/HDP(Local)?-/, '');
}.property('currentStackVersion'),
isHadoop2Stack: function(){
return (stringUtils.compareVersions(this.get('currentStackVersionNumber'), "2.0") === 1 ||
stringUtils.compareVersions(this.get('currentStackVersionNumber'), "2.0") === 0)
}.property('currentStackVersionNumber'),
isHadoop21Stack: function(){
return (stringUtils.compareVersions(this.get('currentStackVersionNumber'), "2.1") === 1 ||
stringUtils.compareVersions(this.get('currentStackVersionNumber'), "2.1") === 0)
}.property('currentStackVersionNumber'),
/**
* If High Availability is enabled
* Based on clusterStatus.isInstalled
, stack version, SNameNode
availability
*
* @type {bool}
*/
isHaEnabled: function() {
if (!this.get('isHadoop2Stack')) return false;
return !this.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE');
}.property('router.clusterController.isLoaded', 'isHadoop2Stack'),
/**
* List of disabled components for the current stack with related info.
* Each element has followed structure:
* @type {Em.Enumerable.}
* @property componentName {String} - name of the component
* @property properties {Object} - mapped properties by site files,
* for example:
* properties: { global_properties: [], site_properties: [], etc. }
* @property reviewConfigs {Ember.Object} - reference review_configs.js
*/
stackDependedComponents: [],
/**
* Restore component data that was excluded from stack.
*
* @param component {Ember.Object} - #stackDependedComponents item
*/
enableComponent: function(component) {
var propertyFileNames = ['global_properties', 'site_properties'];
var requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
// add properties
propertyFileNames.forEach(function(fileName) {
require(requirePrefix + fileName).configProperties = require(requirePrefix + fileName).configProperties.concat(component.get('properties.'+fileName));
});
var reviewConfigsService = require('data/review_configs')
.findProperty('config_name', 'services').config_value
.findProperty('service_name', component.get('serviceName'));
reviewConfigsService.get('service_components').pushObject(component.get('reviewConfigs'));
},
/**
* Disabling component. Remove related data from lists such as
* properties, review configs, service components.
*
* @param component {Object} - stack service component
*
* @return {Ember.Object} - item of stackDependedComponents
property
*/
disableComponent: function(component) {
var componentCopy, propertyFileNames;
var service_configs = require('data/service_configs');
propertyFileNames = ['global_properties', 'site_properties'];
componentCopy = Em.Object.create({
componentName: component.get('componentName'),
serviceName: component.get('serviceName'),
properties: {},
reviewConfigs: {},
configCategory: {}
});
var serviceConfigsCategoryName, requirePrefix, serviceConfig;
// get service category name related to component
serviceConfig = service_configs.findProperty('serviceName', component.get('serviceName'));
serviceConfig.configCategories = serviceConfig.configCategories.filter(function(configCategory) {
if (configCategory.get('hostComponentNames')) {
serviceConfigsCategoryName = configCategory.get('name');
if (configCategory.get('hostComponentNames').contains(component.get('componentName'))) {
componentCopy.set('configCategory', configCategory);
}
}
return true;
});
requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
var propertyObj = {};
propertyFileNames.forEach(function(propertyFileName) {
propertyObj[propertyFileName] = [];
});
// remove config properties related to this component
propertyFileNames.forEach(function(propertyFileName) {
var properties = require(requirePrefix + propertyFileName);
properties.configProperties = properties.configProperties.filter(function(property) {
if (property.category == serviceConfigsCategoryName) {
propertyObj[propertyFileName].push(property);
return false;
} else {
return true;
}
});
});
componentCopy.set('properties', propertyObj);
// remove component from review configs
var reviewConfigsService = require('data/review_configs')
.findProperty('config_name', 'services').config_value
.findProperty('service_name', component.get('serviceName'));
//review_configs might not contain particular service
if (reviewConfigsService) {
reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) {
if (serviceComponent.get('component_name') != component.get('componentName')) {
return true;
} else {
componentCopy.set('reviewConfigs', serviceComponent);
return false;
}
}));
}
return componentCopy;
},
/**
* Resolve dependency in components.
* if component with config category from "data/service_configs" doesn't match components from stack
* then disable it and push to stackDependedComponents
* otherwise enable component and remove it from stackDependedComponents
* Check forbidden/allowed components and
* remove/restore related data.
*
* @method handleStackDependedComponents
*/
handleStackDependedComponents: function () {
// need for unit testing and test mode
if (this.get('handleStackDependencyTest') || this.testMode) return;
var stackDependedComponents = this.get('stackDependedComponents');
var service_configs = require('data/service_configs');
var stackServiceComponents = this.StackServiceComponent.find();
var stackServices = stackServiceComponents.mapProperty('serviceName').uniq();
if (!stackServiceComponents.mapProperty('componentName').length) {
return;
}
// disable components
service_configs.forEach(function (service) {
service.configCategories.forEach(function (serviceConfigCategory) {
var categoryComponents = serviceConfigCategory.get('hostComponentNames');
if (categoryComponents && categoryComponents.length) {
categoryComponents.forEach(function (categoryComponent) {
var stackServiceComponent = stackServiceComponents.findProperty('componentName', categoryComponent);
// populate App.stackDependedComponents if the service config category for the serviceComponent
// exists in the 'data/service_configs.js' and the service to which the component belongs also exists in the
// stack but the serviceComponent does not exists in the stack. Also check App.stackDependedComponents doesn't already have the componentName
if (!stackServiceComponent && stackServices.contains(service.serviceName) &&
!stackDependedComponents.mapProperty('componentName').contains['categoryComponent']) {
var _stackServiceComponent = Ember.Object.create({
componentName: categoryComponent,
serviceName: service.serviceName
});
stackDependedComponents.push(this.disableComponent(_stackServiceComponent));
}
}, this);
}
}, this);
}, this);
// enable components
if (stackDependedComponents.length > 0) {
stackDependedComponents.forEach(function (component) {
if (stackServiceComponents.someProperty('componentName', component.get('componentName'))) {
this.enableComponent(component);
stackDependedComponents.removeObject(component);
}
}, this);
}
this.set('stackDependedComponents', stackDependedComponents);
},
/**
* List of components with allowed action for them
* @type {Em.Object}
*/
components: function() {
return Em.Object.create({
allComponents:this.StackServiceComponent.find().mapProperty('componentName'),
reassignable: this.StackServiceComponent.find().filterProperty('isReassignable',true).mapProperty('componentName'),
restartable: this.StackServiceComponent.find().filterProperty('isRestartable',true).mapProperty('componentName'),
deletable: this.StackServiceComponent.find().filterProperty('isDeletable',true).mapProperty('componentName'),
rollinRestartAllowed: this.StackServiceComponent.find().filterProperty('isRollinRestartAllowed',true).mapProperty('componentName'),
decommissionAllowed: this.StackServiceComponent.find().filterProperty('isDecommissionAllowed',true).mapProperty('componentName'),
refreshConfigsAllowed: this.StackServiceComponent.find().filterProperty('isRefreshConfigsAllowed',true).mapProperty('componentName'),
addableToHost: this.StackServiceComponent.find().filterProperty('isAddableToHost',true).mapProperty('componentName'),
slaves: this.StackServiceComponent.find().filterProperty('isMaster',false).filterProperty('isClient',false).mapProperty('componentName'),
masters: this.StackServiceComponent.find().filterProperty('isMaster',true).mapProperty('componentName'),
clients: this.StackServiceComponent.find().filterProperty('isClient',true).mapProperty('componentName')
});
}.property('App.router.clusterController.isLoaded')
});