123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- /**
- * 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');
- App.HostComponentView = Em.View.extend({
- templateName: require('templates/main/host/details/host_component'),
- /**
- * @type {App.HostComponent}
- */
- content: null,
- excludedMasterCommands: ['DECOMMISSION', 'RECOMMISSION'],
- /**
- * @type {App.HostComponent}
- */
- hostComponent: function () {
- var hostComponent = null;
- var serviceComponent = this.get('content');
- var host = App.router.get('mainHostDetailsController.content');
- if (host) {
- hostComponent = host.get('hostComponents').findProperty('componentName', serviceComponent.get('componentName'));
- }
- return hostComponent;
- }.property('content', 'App.router.mainHostDetailsController.content'),
- /**
- * @type {String}
- */
- workStatus: Em.computed.firstNotBlank('hostComponent.workStatus', 'content.workStatus'),
- /**
- * Return host component text status
- * @type {String}
- */
- componentTextStatus: Em.computed.firstNotBlank('hostComponent.componentTextStatus', 'content.componentTextStatus'),
- /**
- * CSS-class for host component status
- * @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';
- }
- //For all other cases
- return 'health-status-' + App.HostComponentStatus.getKeyName(this.get('workStatus'));
- }.property('workStatus'),
- /**
- * CSS-icon-class for host component status
- * @type {String}
- */
- statusIconClass: function () {
- return Em.getWithDefault({
- 'health-status-started': App.healthIconClassGreen,
- 'health-status-starting': App.healthIconClassGreen,
- 'health-status-installed': App.healthIconClassRed,
- 'health-status-stopping': App.healthIconClassRed,
- 'health-status-unknown': App.healthIconClassYellow,
- 'health-status-DEAD-ORANGE': App.healthIconClassOrange
- }, this.get('statusClass'), '');
- }.property('statusClass'),
- /**
- * CSS-class for disabling drop-down menu with list of host component actions
- * Disabled if host's <code>healthClass</code> is health-status-DEAD-YELLOW (lost heartbeat)
- * Disabled if component's action list is empty
- * @type {String}
- */
- disabled: function () {
- return ( (this.get('parentView.content.healthClass') === "health-status-DEAD-YELLOW") || (this.get('noActionAvailable') === 'hidden' && this.get('isRestartComponentDisabled'))) ? 'disabled' : '';
- }.property('parentView.content.healthClass', 'noActionAvailable', 'isRestartComponentDisabled'),
- /**
- * For Upgrade failed state
- * @type {bool}
- */
- isUpgradeFailed: Em.computed.equal('workStatus', App.HostComponentStatus.upgrade_failed),
- /**
- * For Install failed state
- * @type {bool}
- */
- isInstallFailed: Em.computed.equal('workStatus', App.HostComponentStatus.install_failed),
- /**
- * For Started and Starting states
- * @type {bool}
- */
- isStart: Em.computed.existsIn('workStatus', [App.HostComponentStatus.started, App.HostComponentStatus.starting]),
- /**
- * For Installed state
- * @type {bool}
- */
- isStop: Em.computed.equal('workStatus', App.HostComponentStatus.stopped),
- /**
- * For Installing state
- * @type {bool}
- */
- isInstalling: Em.computed.equal('workStatus', App.HostComponentStatus.installing),
- /**
- * For Init state
- * @type {bool}
- */
- isInit: Em.computed.equal('workStatus', App.HostComponentStatus.init),
- /**
- * For Stopping or Starting states
- * @type {bool}
- */
- isInProgress: Em.computed.existsIn('workStatus', [App.HostComponentStatus.stopping, App.HostComponentStatus.starting]),
- withoutActions: Em.computed.existsIn('workStatus', [App.HostComponentStatus.starting, App.HostComponentStatus.stopping, App.HostComponentStatus.unknown, App.HostComponentStatus.disabled]),
- /**
- * No action available while component is starting/stopping/unknown
- * @type {String}
- */
- noActionAvailable: Em.computed.ifThenElse('withoutActions', 'hidden', ''),
- /**
- * For OFF <code>passiveState</code> of host component
- * @type {bool}
- */
- isActive: Em.computed.equal('content.passiveState', 'OFF'),
- /**
- * Tooltip message for switch maintenance mode option
- * @type {Strting}
- */
- maintenanceTooltip: function () {
- switch (this.get('content.passiveState')) {
- case 'IMPLIED_FROM_SERVICE':
- return Em.I18n.t('passiveState.disabled.impliedFromHighLevel').format(this.get('content.displayName'), this.get('content.service.serviceName'));
- case 'IMPLIED_FROM_HOST':
- return Em.I18n.t('passiveState.disabled.impliedFromHighLevel').format(this.get('content.displayName'), this.get('content.host.hostName'));
- case 'IMPLIED_FROM_SERVICE_AND_HOST':
- return Em.I18n.t('passiveState.disabled.impliedFromServiceAndHost').format(this.get('content.displayName'), this.get('content.service.serviceName'), this.get('content.host.hostName'));
- default:
- return '';
- }
- }.property('content.passiveState'),
- /**
- * Shows whether we need to show Delete button
- * @type {bool}
- */
- isDeletableComponent: function () {
- return App.get('components.deletable').contains(this.get('content.componentName'));
- }.property('content'),
- /**
- * Host component with some <code>workStatus</code> can't be moved (so, disable such action in the dropdown list)
- * @type {boolean}
- */
- isMoveComponentDisabled: function () {
- return App.get('allHostNames').length === App.HostComponent.find().filterProperty('componentName', this.get('content.componentName')).mapProperty('hostName').length;
- }.property('content.componentName', 'App.allHostNames'),
- /**
- * Host component with some <code>workStatus</code> can't be deleted (so, disable such action in the dropdown list)
- * @type {bool}
- */
- isDeleteComponentDisabled: function () {
- var stackComponentCount = App.StackServiceComponent.find(this.get('hostComponent.componentName')).get('minToInstall');
- var installedCount = App.HostComponent.getCount(this.get('hostComponent.componentName'), 'totalCount');
- return (installedCount <= stackComponentCount)
- || ![App.HostComponentStatus.stopped, App.HostComponentStatus.unknown, App.HostComponentStatus.install_failed, App.HostComponentStatus.upgrade_failed, App.HostComponentStatus.init].contains(this.get('workStatus'));
- }.property('workStatus'),
- /**
- * Gets number of current running components that are applied to the cluster
- * @returns {Number}
- */
- runningComponentCounter: function () {
- return App.HostComponent.find().filter(function (component) {
- return (component.get('componentName') === this.get('content.componentName') && [App.HostComponentStatus.started, App.HostComponentStatus.starting].contains(component.get('workStatus')))
- }, this).length;
- },
- /**
- * Check if component may be reassinged to another host
- * @type {bool}
- */
- isReassignable: function () {
- return App.get('components.reassignable').contains(this.get('content.componentName')) && App.router.get('mainHostController.hostsCountMap')['TOTAL'] > 1;
- }.property('content.componentName'),
- /**
- * Check if component is restartable
- * @type {bool}
- */
- isRestartableComponent: function() {
- return App.get('components.restartable').contains(this.get('content.componentName'));
- }.property('content'),
- /**
- * Host component with some <code>workStatus</code> can't be restarted (so, disable such action in the dropdown list)
- * @type {bool}
- */
- isRestartComponentDisabled: Em.computed.notEqual('workStatus', App.HostComponentStatus.started),
- /**
- * Check if component configs can be refreshed
- * @type {bool}
- */
- isRefreshConfigsAllowed: function() {
- return App.get('components.refreshConfigsAllowed').contains(this.get('content.componentName'));
- }.property('content'),
- willInsertElement: function() {
- //make link to view instance to get decommission state
- this.set('content.view', this);
- },
- didInsertElement: function () {
- App.tooltip($('[rel=componentHealthTooltip]'));
- App.tooltip($('[rel=passiveTooltip]'));
- if (this.get('isInProgress')) {
- this.doBlinking();
- }
- },
- /**
- * 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 && !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
- */
- startBlinking: function () {
- this.$('.components-health').stop(true, true);
- this.$('.components-health').css({opacity: 1.0});
- this.doBlinking();
- }.observes('workStatus'),
- /**
- * Get custom commands for slave components
- */
- customCommands: function() {
- var customCommands;
- var hostComponent = this.get('content');
- var component = App.StackServiceComponent.find(hostComponent.get('componentName'));
- customCommands = this.getCustomCommands(component, hostComponent, component.get('isSlave'));
- return customCommands;
- }.property('content', 'workStatus'),
- /**
- * Get a list of custom commands
- *
- * @param component
- * @param hostComponent
- * @param isSlave
- * @returns {Array}
- */
- getCustomCommands: function (component, hostComponent, isSlave) {
- isSlave = isSlave || false;
- if (!component || !hostComponent) {
- return [];
- }
- var self = this;
- var commands = component.get('customCommands');
- var customCommands = [];
- commands.forEach(function(command) {
- if (!isSlave && !self.meetsCustomCommandReq(component, command)) {
- return;
- }
- var commandMap = App.HostComponentActionMap.getMap(self)[command];
- customCommands.push({
- label: self.getCustomCommandLabel(command),
- service: component.get('serviceName'),
- hosts: hostComponent.get('hostName'),
- context: (!!commandMap && !!commandMap.context) ? commandMap.context : null,
- component: component.get('componentName'),
- command: command,
- disabled: !!commandMap ? !!commandMap.disabled : false
- });
- });
- return customCommands;
- },
- /**
- * Get the Label of the custom command
- *
- * @param command
- * @returns {String}
- */
- getCustomCommandLabel: function (command) {
- if (command in App.HostComponentActionMap.getMap(this) && App.HostComponentActionMap.getMap(this)[command].label)
- return App.HostComponentActionMap.getMap(this)[command].label;
-
- return Em.I18n.t('services.service.actions.run.executeCustomCommand.menu').format(App.format.normalizeNameBySeparators(command, ["_", "-", " "]));
- },
- /**
- * The custom command meets the requirements to be active on master
- *
- * @param component
- * @param command
- *
- * @return {Boolean}
- */
- meetsCustomCommandReq: function (component, command) {
- var excludedMasterCommands = this.get('excludedMasterCommands');
- if (excludedMasterCommands.indexOf(command) >= 0) {
- return false;
- }
- if (component.get('cardinality') !== '1') {
- if (!this.get('isStart')) {
- if (App.HostComponent.getCount(this.get('hostComponent.componentName'), 'totalCount') > 1) {
- if (this.runningComponentCounter()) {
- return false;
- }
- } else {
- return false;
- }
- }
- }
- return true;
- }
- });
|