/** * 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 misc = require('utils/misc'); App.MainServiceController = Em.ArrayController.extend({ name: 'mainServiceController', /** * @type {Ember.Object[]} */ content: function () { if (!App.router.get('clusterController.isLoaded')) { return []; } return misc.sortByOrder(App.StackService.find().mapProperty('serviceName'), App.Service.find().toArray()); }.property('App.router.clusterController.isLoaded').volatile(), /** * Current cluster * @type {Ember.Object} */ cluster: function () { if (!App.router.get('clusterController.isClusterDataLoaded')) { return null; } return App.Cluster.find().objectAt(0); }.property('App.router.clusterController.isClusterDataLoaded'), /** * Check if all services are installed * true - all installed, false - not all * @type {bool} */ isAllServicesInstalled: function () { if (!this.get('content')) return false; var availableServices = App.StackService.find().mapProperty('serviceName'); return this.get('content').length == availableServices.length; }.property('content.@each', 'content.length'), /** * Should "Start All"-button be disabled * @type {bool} */ isStartAllDisabled: function () { if (this.get('isStartStopAllClicked') == true) { return true; } var stoppedServices = this.get('content').filter(function (_service) { return (_service.get('healthStatus') === 'red' && !App.get('services.clientOnly').contains(_service.get('serviceName'))); }); return (stoppedServices.length === 0); // all green status }.property('isStartStopAllClicked', 'content.@each.healthStatus'), /** * Should "Stop All"-button be disabled * @type {bool} */ isStopAllDisabled: function () { if (this.get('isStartStopAllClicked') == true) { return true; } return !this.get('content').someProperty('healthStatus', 'green'); }.property('isStartStopAllClicked', 'content.@each.healthStatus'), /** * Should "Refresh All"-button be disabled * @type {bool} */ isRestartAllRequiredDisabled: Em.computed.everyBy('content', 'isRestartRequired', false), /** * @type {bool} */ isStartStopAllClicked: Em.computed.notEqual('App.router.backgroundOperationsController.allOperationsCount', 0), /** * Callback for start all service button * @return {App.ModalPopup|null} * @method startAllService */ startAllService: function (event) { return this.startStopAllService(event, 'STARTED'); }, /** * Callback for stop all service button * @return {App.ModalPopup|null} * @method stopAllService */ stopAllService: function (event) { return this.startStopAllService(event, 'INSTALLED'); }, /** * Common method for "start-all", "stop-all" calls * @param {object} event * @param {string} state 'STARTED|INSTALLED' * @returns {App.ModalPopup|null} * @method startStopAllService */ startStopAllService: function(event, state) { if ($(event.target).hasClass('disabled') || $(event.target.parentElement).hasClass('disabled')) { return null; } var self = this; var bodyMessage = Em.Object.create({ confirmMsg: state == 'INSTALLED' ? Em.I18n.t('services.service.stopAll.confirmMsg') : Em.I18n.t('services.service.startAll.confirmMsg'), confirmButton: state == 'INSTALLED' ? Em.I18n.t('services.service.stop.confirmButton') : Em.I18n.t('services.service.start.confirmButton') }); if (state == 'INSTALLED' && App.Service.find().filterProperty('serviceName', 'HDFS').someProperty('workStatus', App.HostComponentStatus.started)) { App.router.get('mainServiceItemController').checkNnLastCheckpointTime(function () { return App.showConfirmationFeedBackPopup(function (query) { self.allServicesCall(state, query); }, bodyMessage); }); } else { return App.showConfirmationFeedBackPopup(function (query) { self.allServicesCall(state, query); }, bodyMessage); } }, /** * Do request to server for "start|stop" all services * @param {string} state "STARTED|INSTALLED" * @param {object} query * @method allServicesCall * @return {$.ajax} */ allServicesCall: function (state, query) { var context = (state == 'INSTALLED') ? App.BackgroundOperationsController.CommandContexts.STOP_ALL_SERVICES : App.BackgroundOperationsController.CommandContexts.START_ALL_SERVICES; return App.ajax.send({ name: 'common.services.update', sender: this, data: { context: context, ServiceInfo: { state: state }, query: query }, success: 'allServicesCallSuccessCallback', error: 'allServicesCallErrorCallback' }); }, /** * Restart all services - stops all services, then starts them back */ restartAllServices: function () { this.silentStopAllServices(); }, /** * Silent stop all services - without user confirmation * @returns {$.ajax} */ silentStopAllServices: function () { return App.ajax.send({ name: 'common.services.update', sender: this, data: { context: App.BackgroundOperationsController.CommandContexts.STOP_ALL_SERVICES, ServiceInfo: { state: 'INSTALLED' } }, success: 'silentStopSuccess' }); }, isStopAllServicesFailed: function() { var workStatuses = App.Service.find().mapProperty('workStatus'); for (var i = 0; i < workStatuses.length; i++) { if (workStatuses[i] !== 'INSTALLED' && workStatuses[i] !== 'STOPPING') { return true; } } return false; }, /** * Success callback for silent stop */ silentStopSuccess: function () { var self = this; App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) { if (initValue) { App.router.get('backgroundOperationsController').showPopup(); } Em.run.later(function () { self.set('shouldStart', true); }, App.bgOperationsUpdateInterval); }); }, /** * Silent start all services - without user confirmation */ silentStartAllServices: function () { if ( !App.router.get('backgroundOperationsController').get('allOperationsCount') && this.get('shouldStart') && !this.isStopAllServicesFailed() ) { this.set('shouldStart', false); return App.ajax.send({ name: 'common.services.update', sender: this, data: { context: App.BackgroundOperationsController.CommandContexts.START_ALL_SERVICES, ServiceInfo: { state: 'STARTED' } }, success: 'silentCallSuccessCallback' }); } }.observes('shouldStart', 'controllers.backgroundOperationsController.allOperationsCount'), /** * Success callback for silent start */ silentCallSuccessCallback: function () { // load data (if we need to show this background operations popup) from persist App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) { if (initValue) { App.router.get('backgroundOperationsController').showPopup(); } }); }, /** * Success-callback for all-services request * @param {object} data * @param {object} xhr * @param {object} params * @method allServicesCallSuccessCallback */ allServicesCallSuccessCallback: function (data, xhr, params) { params.query.set('status', 'SUCCESS'); // load data (if we need to show this background operations popup) from persist App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) { if (initValue) { App.router.get('backgroundOperationsController').showPopup(); } }); }, /** * Error-callback for all-services request * @param {object} request * @param {object} ajaxOptions * @param {string} error * @param {object} opt * @param {object} params * @method allServicesCallErrorCallback */ allServicesCallErrorCallback: function (request, ajaxOptions, error, opt, params) { params.query.set('status', 'FAIL'); }, /** * "Add-service"-click handler * @method gotoAddService */ gotoAddService: function () { if (this.get('isAllServicesInstalled')) { return; } App.router.get('addServiceController').setDBProperty('onClosePath', 'main.services.index'); App.router.transitionTo('main.serviceAdd'); }, /** * Show confirmation popup and send request to restart all host components with stale_configs=true */ restartAllRequired: function () { var self = this; if (!this.get('isRestartAllRequiredDisabled')) { return App.showConfirmationPopup(function () { self.restartHostComponents(); }, Em.I18n.t('services.service.refreshAll.confirmMsg').format( App.HostComponent.find().filterProperty('staleConfigs').mapProperty('service.displayName').uniq().join(', ')), null, null, Em.I18n.t('services.service.restartAll.confirmButton') ); } else { return null; } }, /** * Send request restart host components from hostComponentsToRestart * @returns {$.ajax} */ restartHostComponents: function () { var batches, hiveInteractive = App.HostComponent.find().findProperty('componentName', 'HIVE_SERVER_INTERACTIVE'); var isYARNQueueRefreshRequired = hiveInteractive && hiveInteractive.get('staleConfigs'); var ajaxData = { "RequestInfo": { "command": "RESTART", "context": "Restart all required services", "operation_level": "host_component" }, "Requests/resource_filters": [ { "hosts_predicate": "HostRoles/stale_configs=true" } ] }; if (isYARNQueueRefreshRequired) { batches = [ { "order_id": 1, "type": "POST", "uri": App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests", "RequestBodyInfo": { "RequestInfo": { "context": "Refresh YARN Capacity Scheduler", "command": "REFRESHQUEUES", "parameters/forceRefreshConfigTags": "capacity-scheduler" }, "Requests/resource_filters": [{ "service_name": "YARN", "component_name": "RESOURCEMANAGER", "hosts": App.HostComponent.find().findProperty('componentName', 'RESOURCEMANAGER').get('hostName') }] } }, { "order_id": 2, "type": "POST", "uri": App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests", "RequestBodyInfo": ajaxData } ]; App.ajax.send({ name: 'common.batch.request_schedules', sender: this, data: { intervalTimeSeconds: 1, tolerateSize: 0, batches: batches }, success: 'restartAllRequiredSuccessCallback' }); } else { App.ajax.send({ name: 'request.post', sender: this, data: ajaxData, success: 'restartAllRequiredSuccessCallback' }); } }, /** * Success callback for restartAllRequired */ restartAllRequiredSuccessCallback: function () { // load data (if we need to show this background operations popup) from persist App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) { if (initValue) { App.router.get('backgroundOperationsController').showPopup(); } }); } });