123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101 |
- /**
- * 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 batchUtils = require('utils/batch_scheduled_requests');
- var date = require('utils/date/date');
- var fileUtils = require('utils/file_utils');
- /**
- * @typedef {object} TaskRelationObject
- * @property {string} type relation type 'service', 'component'
- * @property {string} [value] optional value of relation e.g. name of component or service
- */
- /**
- * Option for "filter by state" dropdown
- * @typedef {object} progressPopupCategoryObject
- * @property {string} value "all|pending|in progress|failed|completed|aborted|timedout"
- * @property {number} count number of items with <code>state</code> equal to <code>this.value</code>
- * @property {string} labelPath key in the messages.js
- * @property {string} label localized label
- */
- var categoryObject = Em.Object.extend({
- value: '',
- count: 0,
- labelPath: '',
- label: function () {
- return Em.I18n.t(this.get('labelPath')).format(this.get('count'));
- }.property('count', 'labelPath')
- });
- /**
- * @class HostProgressPopupBodyView
- * @type {Em.View}
- */
- App.HostProgressPopupBodyView = App.TableView.extend({
- templateName: require('templates/common/host_progress_popup'),
- /**
- * @type {boolean}
- */
- showTextArea: false,
- /**
- * @type {boolean}
- */
- isServiceEmptyList: true,
- /**
- * @type {boolean}
- */
- isTasksEmptyList: true,
- /**
- * @type {number}
- */
- sourceRequestScheduleId: -1,
- /**
- * @type {boolean}
- */
- sourceRequestScheduleRunning: false,
- /**
- * @type {boolean}
- */
- sourceRequestScheduleAborted: false,
- /**
- * @type {?string}
- */
- sourceRequestScheduleCommand: null,
- /**
- * @type {string}
- */
- clipBoardContent: null,
- isClipBoardActive: false,
- /**
- * Determines that host information become loaded and mapped with <code>App.hostsMapper</code>.
- * This property play in only when Log Search service installed.
- *
- * @type {boolean}
- */
- hostInfoLoaded: true,
- /**
- * Alias for <code>controller.hosts</code>
- *
- * @type {wrappedHost[]}
- */
- hosts: function () {
- return this.get('controller.hosts')
- }.property('controller.hosts.[]'),
- /**
- * Alias for <code>controller.servicesInfo</code>
- *
- * @type {wrappedService[]}
- */
- services: function () {
- return this.get('controller.servicesInfo');
- }.property('controller.servicesInfo.[]'),
- /**
- * @type {number}
- */
- openedTaskId: 0,
- /**
- * Return task detail info of opened task
- *
- * @type {wrappedTask}
- */
- openedTask: function () {
- if (!(this.get('openedTaskId') && this.get('tasks'))) {
- return Em.Object.create();
- }
- return this.get('tasks').findProperty('id', this.get('openedTaskId'));
- }.property('tasks', 'tasks.@each.stderr', 'tasks.@each.stdout', 'openedTaskId'),
- /**
- * @type {object}
- */
- filterMap: {
- pending: ["pending", "queued"],
- in_progress: ["in_progress", "upgrading"],
- failed: ["failed"],
- completed: ["completed", "success"],
- aborted: ["aborted"],
- timedout: ["timedout"]
- },
- /**
- * Determines if "Show More ..."-link should be shown
- * @type {boolean}
- */
- isShowMore: true,
- /**
- * @type {boolean}
- */
- pagination: true,
- /**
- * @type {boolean}
- */
- isPaginate: false,
- /**
- * Select box, display names and values
- *
- * @type {progressPopupCategoryObject[]}
- */
- categories: [
- categoryObject.create({value: 'all', labelPath: 'hostPopup.status.category.all'}),
- categoryObject.create({value: 'pending', labelPath: 'hostPopup.status.category.pending'}),
- categoryObject.create({value: 'in_progress', labelPath: 'hostPopup.status.category.inProgress'}),
- categoryObject.create({value: 'failed', labelPath: 'hostPopup.status.category.failed'}),
- categoryObject.create({value: 'completed', labelPath: 'hostPopup.status.category.success'}),
- categoryObject.create({value: 'aborted', labelPath: 'hostPopup.status.category.aborted'}),
- categoryObject.create({value: 'timedout', labelPath: 'hostPopup.status.category.timedout'})
- ],
- /**
- * Selected option is bound to this values
- * @type {?progressPopupCategoryObject}
- */
- serviceCategory: null,
- /**
- * @type {?progressPopupCategoryObject}
- */
- hostCategory: null,
- /**
- * @type {?progressPopupCategoryObject}
- */
- taskCategory: null,
- /**
- * flag to indicate whether level data has already been loaded
- * applied only to HOSTS_LIST and TASK_DETAILS levels, whereas async query used to obtain data
- *
- * @type {boolean}
- */
- isLevelLoaded: true,
- /**
- * <code>switchLevel</code> for some <code>controller.dataSourceController</code> should be customized
- * So, this map contains information about customize-methods
- * Format: key - <code>dataSourceController.name</code>, value - method name in this view
- * Method is called with same arguments as <code>switchLevel</code> is
- *
- * @type {object}
- */
- customControllersSwitchLevelMap: {
- highAvailabilityProgressPopupController: '_switchLevelForHAProgressPopupController'
- },
- /**
- * @type {boolean}
- */
- isHostEmptyList: Em.computed.empty('pageContent'),
- /**
- * @type {wrappedHost}
- */
- currentHost: function () {
- return this.get('hosts') && this.get('hosts').findProperty('name', this.get('controller.currentHostName'));
- }.property('controller.currentHostName'),
- /**
- * Tasks for current shown host (<code>currentHost</code>)
- *
- * @type {wrappedTask[]}
- */
- tasks: function () {
- var currentHost = this.get('currentHost');
- return currentHost ? currentHost.get('tasks') : [];
- }.property('currentHost.tasks', 'currentHost.tasks.@each.status'),
- /**
- * Message about aborting operation
- * Custom for Rolling Restart
- *
- * @type {string}
- */
- requestScheduleAbortLabel: function () {
- return 'ROLLING-RESTART' == this.get('sourceRequestScheduleCommand') ?
- Em.I18n.t("hostPopup.bgop.abort.rollingRestart"):
- Em.I18n.t("common.abort");
- }.property('sourceRequestScheduleCommand'),
- didInsertElement: function () {
- this.updateHostInfo();
- this.subscribeResize();
- },
- willDestroyElement: function () {
- if (this.get('controller.dataSourceController.name') == 'highAvailabilityProgressPopupController') {
- this.set('controller.dataSourceController.isTaskPolling', false);
- }
- this.unsubscribeResize();
- },
- /**
- * Subscribe for window <code>resize</code> event.
- *
- * @method subscribeResize
- */
- subscribeResize: function() {
- var self = this;
- $(window).on('resize', this.resizeHandler.bind(this));
- Em.run.next(this, function() {
- self.resizeHandler();
- });
- },
- /**
- * Remove event listener for window <code>resize</code> event.
- */
- unsubscribeResize: function() {
- $(window).off('resize', this.resizeHandler.bind(this));
- },
- /**
- * This method handles window resize and fit modal body content according to visible items for each <code>level</code>.
- *
- * @method resizeHandler
- */
- resizeHandler: function() {
- if (this.get('state') === 'destroyed' || !this.get('parentView.isOpen')) return;
- var headerHeight = 48,
- modalFooterHeight = 60,
- taskTopWrapHeight = 40,
- modalTopOffset = $('.modal').offset().top,
- contentPaddingBottom = 40,
- hostsPageBarHeight = 45,
- tabbedContentNavHeight = 68,
- logComponentFileNameHeight = 30,
- levelName = this.get('currentLevelName'),
- boLevelHeightMap = {
- 'REQUESTS_LIST': {
- height: window.innerHeight - 2*modalTopOffset - headerHeight - taskTopWrapHeight - modalFooterHeight - contentPaddingBottom,
- target: '#service-info'
- },
- 'HOSTS_LIST': {
- height: window.innerHeight - 2*modalTopOffset - headerHeight - taskTopWrapHeight - modalFooterHeight - contentPaddingBottom - hostsPageBarHeight,
- target: '#host-info'
- },
- 'TASKS_LIST': {
- height: window.innerHeight - 2*modalTopOffset - headerHeight - taskTopWrapHeight - modalFooterHeight - contentPaddingBottom,
- target: '#host-log'
- },
- 'TASK_DETAILS': {
- height: window.innerHeight - 2*modalTopOffset - headerHeight - taskTopWrapHeight - modalFooterHeight - contentPaddingBottom,
- target: ['.task-detail-log-info', '.log-tail-content.pre-styled']
- }
- },
- currentLevelHeight,
- resizeTarget;
- if (levelName && levelName in boLevelHeightMap) {
- resizeTarget = boLevelHeightMap[levelName].target;
- currentLevelHeight = boLevelHeightMap[levelName].height;
- if (levelName === 'TASK_DETAILS' && $('.task-detail-info').hasClass('task-detail-info-tabbed')) {
- currentLevelHeight -= tabbedContentNavHeight;
- }
- if (!Em.isArray(resizeTarget)) {
- resizeTarget = [resizeTarget];
- }
- resizeTarget.forEach(function(target) {
- if (target === '.log-tail-content.pre-styled') {
- currentLevelHeight -= logComponentFileNameHeight;
- }
- $(target).css('maxHeight', currentLevelHeight + 'px');
- });
- }
- },
- currentLevelName: function() {
- return this.get('controller.dataSourceController.levelInfo.name');
- }.property('controller.dataSourceController.levelInfo.name'),
- /**
- * Preset values on init
- *
- * @method setOnStart
- */
- setOnStart: function () {
- this.set('serviceCategory', this.get('categories').findProperty('value', 'all'));
- if (this.get("controller.isBackgroundOperations")) {
- this.get('controller').setSelectCount(this.get("services"), this.get('categories'));
- this.updateHostInfo();
- }
- else {
- this.set("parentView.isHostListHidden", false);
- this.set("parentView.isServiceListHidden", true);
- }
- },
- /**
- * force popup to show list of operations
- *
- * @method resetState
- */
- resetState: function () {
- if (this.get('parentView.isOpen')) {
- this.get('parentView').setProperties({
- isLogWrapHidden: true,
- isTaskListHidden: true,
- isHostListHidden: true,
- isServiceListHidden: false
- });
- this.get("controller").setBackgroundOperationHeader(false);
- this.get('controller.hosts').clear();
- this.setOnStart();
- this.rerender();
- }
- }.observes('parentView.isOpen'),
- /**
- * When popup is opened, and data after polling has changed, update this data in component
- *
- * @method updateHostInfo
- */
- updateHostInfo: function () {
- if (!this.get('parentView.isOpen')) {
- return;
- }
- this.set('parentView.isLoaded', false);
- this.get("controller").set("inputData", this.get("controller.dataSourceController.services"));
- this.get("controller").onServiceUpdate(this.get('parentView.isServiceListHidden'));
- this.get("controller").onHostUpdate();
- this.set('parentView.isLoaded', true);
- this.set("hosts", this.get("controller.hosts"));
- this.set("services", this.get("controller.servicesInfo"));
- this.set('isLevelLoaded', true);
- }.observes("controller.dataSourceController.serviceTimestamp"),
- /**
- * Depending on service filter, set which services should be shown
- *
- * @method visibleServices
- */
- visibleServices: function () {
- if (this.get("services")) {
- this.set("isServiceEmptyList", true);
- if (this.get('serviceCategory.value')) {
- var filter = this.get('serviceCategory.value');
- var services = this.get('services');
- this.set("isServiceEmptyList", this.setVisibility(filter, services));
- }
- }
- }.observes('serviceCategory', 'services', 'services.@each.status'),
- /**
- * Depending on hosts filter, set which hosts should be shown
- *
- * @method filter
- */
- filter: function () {
- var filter = this.get('hostCategory.value');
- var hosts = this.get('hosts') || [];
- var filterMap = this.get('filterMap');
- if (!filter || !hosts.length) {
- return;
- }
- if (filter === 'all') {
- this.set('filteredContent', hosts);
- }
- else {
- this.set('filteredContent', hosts.filter(function (item) {
- return filterMap[filter].contains(item.status);
- }));
- }
- }.observes('hosts.length', 'hostCategory.value'),
- /**
- * Reset startIndex property back to 1 when filter type has been changed.
- *
- * @method resetIndex
- */
- resetIndex: function () {
- if (this.get('hostCategory.value')) {
- this.set('startIndex', 1);
- }
- }.observes('hostCategory.value'),
- /**
- * Depending on tasks filter, set which tasks should be shown
- *
- * @method visibleTasks
- */
- visibleTasks: function () {
- this.set("isTasksEmptyList", true);
- if (this.get('taskCategory.value') && this.get('tasks')) {
- var filter = this.get('taskCategory.value');
- var tasks = this.get('tasks');
- this.set("isTasksEmptyList", this.setVisibility(filter, tasks));
- }
- }.observes('taskCategory', 'tasks', 'tasks.@each.status'),
- /**
- * Depending on selected filter type, set object visibility value
- *
- * @param filter
- * @param obj
- * @return {bool} isEmptyList
- * @method setVisibility
- */
- setVisibility: function (filter, obj) {
- var isEmptyList = true;
- var filterMap = this.get('filterMap');
- if (filter == "all") {
- obj.setEach("isVisible", true);
- isEmptyList = !obj.length;
- }
- else {
- obj.forEach(function (item) {
- item.set('isVisible', filterMap[filter].contains(item.status));
- isEmptyList = (isEmptyList) ? !item.get('isVisible') : false;
- }, this)
- }
- return isEmptyList;
- },
- /**
- * Depending on currently viewed tab, call setSelectCount function
- *
- * @method updateSelectView
- */
- updateSelectView: function () {
- var isPaginate;
- if (this.get('parentView.isHostListHidden')) {
- if (this.get('parentView.isTaskListHidden')) {
- if (!this.get('parentView.isServiceListHidden')) {
- this.get('controller').setSelectCount(this.get("services"), this.get('categories'));
- }
- }
- else {
- this.get('controller').setSelectCount(this.get("tasks"), this.get('categories'));
- }
- }
- else {
- //since lazy loading used for hosts, we need to get hosts info directly from controller, that always contains entire array of data
- this.get('controller').setSelectCount(this.get("controller.hosts"), this.get('categories'));
- isPaginate = true;
- }
- this.set('isPaginate', !!isPaginate);
- }.observes('tasks.@each.status', 'hosts.@each.status', 'parentView.isTaskListHidden', 'parentView.isHostListHidden', 'services.length', 'services.@each.status'),
- /**
- * control data uploading, depending on which display level is showed
- *
- * @param {string} levelName
- * @method switchLevel
- */
- switchLevel: function (levelName) {
- var dataSourceController = this.get('controller.dataSourceController');
- var args = [].slice.call(arguments);
- this.get('hostComponentLogs').clear();
- if (this.get("controller.isBackgroundOperations")) {
- var levelInfo = dataSourceController.get('levelInfo');
- levelInfo.set('taskId', this.get('openedTaskId'));
- levelInfo.set('requestId', this.get('controller.currentServiceId'));
- levelInfo.set('name', levelName);
- if (levelName === 'HOSTS_LIST') {
- this.set('isLevelLoaded', dataSourceController.requestMostRecent());
- this.set('hostCategory', this.get('categories').findProperty('value', 'all'));
- }
- else {
- if (levelName === 'TASK_DETAILS') {
- dataSourceController.requestMostRecent();
- this.set('isLevelLoaded', false);
- }
- else {
- if (levelName === 'REQUESTS_LIST') {
- this.set('serviceCategory', this.get('categories').findProperty('value', 'all'));
- this.get('controller.hosts').clear();
- dataSourceController.requestMostRecent();
- }
- else {
- this.set('taskCategory', this.get('categories').findProperty('value', 'all'));
- }
- }
- }
- }
- else {
- var customControllersSwitchLevelMap = this.get('customControllersSwitchLevelMap');
- Em.tryInvoke(this, customControllersSwitchLevelMap[dataSourceController.get('name')], args);
- }
- },
- levelDidChange: function() {
- var levelName = this.get('controller.dataSourceController.levelInfo.name'),
- self = this;
- if (levelName && this.get('isLevelLoaded')) {
- Em.run.next(this, function() {
- self.resizeHandler();
- });
- }
- }.observes('controller.dataSourceController.levelInfo.name', 'isLevelLoaded'),
- popupIsOpenDidChange: function() {
- if (!this.get('isOpen')) {
- this.get('hostComponentLogs').clear();
- }
- }.observes('parentView.isOpen'),
- /**
- * Switch-level custom method for <code>highAvailabilityProgressPopupController</code>
- *
- * @param {string} levelName
- * @private
- */
- _switchLevelForHAProgressPopupController: function (levelName) {
- var dataSourceController = this.get('controller.dataSourceController');
- if (levelName === 'TASK_DETAILS') {
- this.set('isLevelLoaded', false);
- dataSourceController.startTaskPolling(this.get('openedTask.request_id'), this.get('openedTask.id'));
- Em.keys(this.get('parentView.detailedProperties')).forEach(function (key) {
- dataSourceController.addObserver('taskInfo.' + this.get('parentView.detailedProperties')[key], this, 'updateTaskInfo');
- }, this);
- }
- else {
- dataSourceController.stopTaskPolling();
- }
- },
- /**
- * @method updateTaskInfo
- */
- updateTaskInfo: function () {
- var dataSourceController = this.get('controller.dataSourceController');
- var openedTask = this.get('openedTask');
- if (openedTask && openedTask.get('id') == dataSourceController.get('taskInfo.id')) {
- this.set('isLevelLoaded', true);
- Em.keys(this.get('parentView.detailedProperties')).forEach(function (key) {
- openedTask.set(key, dataSourceController.get('taskInfo.' + key));
- }, this);
- }
- },
- /**
- * Onclick handler for button <-Tasks
- *
- * @method backToTaskList
- */
- backToTaskList: function () {
- this.destroyClipBoard();
- this.set("openedTaskId", 0);
- this.set("parentView.isLogWrapHidden", true);
- this.set("parentView.isTaskListHidden", false);
- this.switchLevel("TASKS_LIST");
- },
- /**
- * Onclick handler for button <-Hosts
- *
- * @method backToHostList
- */
- backToHostList: function () {
- this.set("parentView.isHostListHidden", false);
- this.set("parentView.isTaskListHidden", true);
- this.get("controller").set("popupHeaderName", this.get("controller.serviceName"));
- this.get("controller").set("operationInfo", this.get('controller.servicesInfo').findProperty('name', this.get('controller.serviceName')));
- this.switchLevel("HOSTS_LIST");
- },
- /**
- * Onclick handler for button <-Services
- *
- * @method backToServiceList
- */
- backToServiceList: function () {
- this.get("controller").set("serviceName", "");
- this.set("parentView.isHostListHidden", true);
- this.set("parentView.isServiceListHidden", false);
- this.set("parentView.isTaskListHidden", true);
- this.set("parentView.isLogWrapHidden", true);
- this.set("hosts", null);
- this.get("controller").setBackgroundOperationHeader(false);
- this.switchLevel("REQUESTS_LIST");
- },
- /**
- * Onclick handler for Show more ..
- *
- * @method requestMoreOperations
- */
- requestMoreOperations: function () {
- var BGOController = App.router.get('backgroundOperationsController');
- var count = BGOController.get('operationsCount');
- BGOController.set('operationsCount', (count + 10));
- BGOController.requestMostRecent();
- },
- /**
- * @method setShowMoreAvailable
- */
- setShowMoreAvailable: function () {
- if (this.get('parentView.isOpen')) {
- this.set('isShowMore', App.router.get("backgroundOperationsController.isShowMoreAvailable"));
- }
- }.observes('parentView.isOpen', 'App.router.backgroundOperationsController.isShowMoreAvailable'),
- /**
- * Onclick handler for selected Service
- *
- * @param {{context: wrappedService}} event
- * @method gotoHosts
- */
- gotoHosts: function (event) {
- this.get("controller").set("serviceName", event.context.get("name"));
- this.get("controller").set("currentServiceId", event.context.get("id"));
- this.get("controller").set("currentHostName", null);
- this.get("controller").onHostUpdate();
- this.switchLevel("HOSTS_LIST");
- var servicesInfo = this.get("controller.hosts");
- this.set("controller.popupHeaderName", event.context.get("name"));
- this.set("controller.operationInfo", event.context);
- //apply lazy loading on cluster with more than 100 nodes
- this.set('hosts', servicesInfo.length > 100 ? servicesInfo.slice(0, 50) : servicesInfo);
- this.set("parentView.isServiceListHidden", true);
- this.set("parentView.isHostListHidden", false);
- this.set("parentView.isTaskListHidden", true);
- $(".modal").scrollTop(0);
- $(".modal-body").scrollTop(0);
- if (servicesInfo.length > 100) {
- Em.run.next(this, function () {
- this.set('hosts', this.get('hosts').concat(servicesInfo.slice(50, servicesInfo.length)));
- });
- }
- // Determine if source request schedule is present
- this.set('sourceRequestScheduleId', event.context.get("sourceRequestScheduleId"));
- this.set('sourceRequestScheduleCommand', event.context.get('contextCommand'));
- this.refreshRequestScheduleInfo();
- },
- /**
- * Navigate to host details logs tab with preset filter.
- */
- navigateToHostLogs: function() {
- var relationType = this._determineRoleRelation(this.get('openedTask')),
- hostModel = App.Host.find().findProperty('hostName', this.get('openedTask.hostName')),
- queryParams = [],
- model;
- if (relationType.type === 'component') {
- model = App.StackServiceComponent.find().findProperty('componentName', relationType.value);
- queryParams.push('service_name=' + model.get('serviceName'));
- queryParams.push('component_name=' + relationType.value);
- }
- if (relationType.type === 'service') {
- queryParams.push('service_name=' + relationType.value);
- }
- App.router.transitionTo('main.hosts.hostDetails.logs', hostModel, { query: ''});
- if (this.get('parentView') && typeof this.get('parentView').onClose === 'function') this.get('parentView').onClose();
- },
- /**
- /**
- * Determines if opened task related to service or component.
- *
- * @return {boolean} <code>true</code> when relates to service or component
- */
- isLogsLinkVisible: function() {
- if (!this.get('openedTask') || !this.get('openedTask.id')) return false;
- return !!this._determineRoleRelation(this.get('openedTask'));
- }.property('openedTask'),
- /**
- * @param {wrappedTask} taskInfo
- * @return {boolean|TaskRelationObject}
- */
- _determineRoleRelation: function(taskInfo) {
- var foundComponentName,
- foundServiceName,
- componentNames = App.StackServiceComponent.find().mapProperty('componentName'),
- serviceNames = App.StackService.find().mapProperty('serviceName'),
- taskLog = this.get('currentHost.logTasks').findProperty('Tasks.id', Em.get(taskInfo, 'id')) || {},
- role = Em.getWithDefault(taskLog, 'Tasks.role', false),
- eqlFn = function(compare) {
- return function(item) {
- return item === compare;
- };
- };
- if (!role) {
- return false;
- }
- // component service check
- if (role.endsWith('_SERVICE_CHECK')) {
- role = role.replace('_SERVICE_CHECK', '');
- }
- foundComponentName = componentNames.filter(eqlFn(role))[0];
- foundServiceName = serviceNames.filter(eqlFn(role))[0];
- if (foundComponentName || foundServiceName) {
- return {
- type: foundComponentName ? 'component' : 'service',
- value: foundComponentName || foundServiceName
- }
- }
- return false;
- },
- /**
- * @type {boolean}
- */
- isRequestSchedule: function () {
- var id = this.get('sourceRequestScheduleId');
- return id != null && !isNaN(id) && id > -1;
- }.property('sourceRequestScheduleId'),
- /**
- * @method refreshRequestScheduleInfo
- */
- refreshRequestScheduleInfo: function () {
- var self = this;
- var id = this.get('sourceRequestScheduleId');
- batchUtils.getRequestSchedule(id, function (data) {
- var status = Em.get(data || {}, 'RequestSchedule.status');
- if (status) {
- switch (status) {
- case 'DISABLED':
- self.set('sourceRequestScheduleRunning', false);
- self.set('sourceRequestScheduleAborted', true);
- break;
- case 'COMPLETED':
- self.set('sourceRequestScheduleRunning', false);
- self.set('sourceRequestScheduleAborted', false);
- break;
- case 'SCHEDULED':
- self.set('sourceRequestScheduleRunning', true);
- self.set('sourceRequestScheduleAborted', false);
- break;
- }
- }
- else {
- self.set('sourceRequestScheduleRunning', false);
- self.set('sourceRequestScheduleAborted', false);
- }
- }, function () {
- self.set('sourceRequestScheduleRunning', false);
- self.set('sourceRequestScheduleAborted', false);
- });
- }.observes('sourceRequestScheduleId'),
- /**
- * Attempts to abort the current request schedule
- *
- * @param {{context: number}} event
- * @method doAbortRequestSchedule
- */
- doAbortRequestSchedule: function (event) {
- var self = this;
- var id = event.context;
- batchUtils.doAbortRequestSchedule(id, function () {
- self.refreshRequestScheduleInfo();
- });
- },
- /**
- * Onclick handler for selected Host
- *
- * @param {{context: wrappedHost}} event
- * @method gotoTasks
- */
- gotoTasks: function (event) {
- var tasksInfo = [];
- event.context.logTasks.forEach(function (_task) {
- tasksInfo.pushObject(this.get("controller").createTask(_task));
- }, this);
- if (tasksInfo.length) {
- this.get("controller").set("popupHeaderName", event.context.publicName);
- this.get("controller").set("currentHostName", event.context.publicName);
- }
- this.switchLevel("TASKS_LIST");
- this.set('currentHost.tasks', tasksInfo);
- this.set("parentView.isHostListHidden", true);
- this.set("parentView.isTaskListHidden", false);
- this.preloadHostModel(Em.getWithDefault(event.context || {}, 'name', false));
- $(".modal").scrollTop(0);
- $(".modal-body").scrollTop(0);
- },
- /**
- * Will add <code>App.Host</code> model with relevant host info by specified host name only when it missed
- * and Log Search service installed.
- * This update needed to get actual status of logs for components located on this host and get appropriate model
- * for navigation to hosts/:host_id/logs route.
- *
- * @method preloadHostModel
- * @param {string} hostName host name to get info
- */
- preloadHostModel: function(hostName) {
- var self = this,
- fields;
- if (!hostName) {
- self.set('hostInfoLoaded', true);
- return;
- }
- if (this.get('isLogSearchInstalled') && App.get('supports.logSearch') && !App.Host.find().someProperty('hostName', hostName)) {
- this.set('hostInfoLoaded', false);
- fields = ['stack_versions/repository_versions/RepositoryVersions/repository_version',
- 'host_components/HostRoles/host_name'];
- App.router.get('updateController').updateLogging(hostName, fields, function(data) {
- App.hostsMapper.map({ items: [data] });
- }).always(function() {
- self.set('hostInfoLoaded', true);
- });
- } else {
- self.set('hostInfoLoaded', true);
- }
- },
- /**
- * @method stopRebalanceHDFS
- * @returns {App.ModalPopup}
- */
- stopRebalanceHDFS: function () {
- var hostPopup = this;
- return App.showConfirmationPopup(function () {
- App.ajax.send({
- name: 'cancel.background.operation',
- sender: hostPopup,
- data: {
- requestId: hostPopup.get('controller.currentServiceId')
- }
- });
- hostPopup.backToServiceList();
- });
- },
- /**
- * Onclick handler for selected Task
- *
- * @method openTaskLogInDialog
- */
- openTaskLogInDialog: function () {
- var target = ".task-detail-log-info",
- activeHostLog = this.get('hostComponentLogs').findProperty('isActive', true),
- activeHostLogSelector = activeHostLog ? activeHostLog.get('tabClassNameSelector') + '.active' : false;
- if ($(".task-detail-log-clipboard").length) {
- this.destroyClipBoard();
- }
- if (activeHostLog && $(activeHostLogSelector).length) {
- target = activeHostLogSelector;
- }
- var newWindow = window.open();
- var newDocument = newWindow.document;
- newDocument.write($(target).html());
- newDocument.close();
- },
- /**
- * Onclick event for show task detail info
- *
- * @param {{context: wrappedTask}} event
- * @method toggleTaskLog
- */
- toggleTaskLog: function (event) {
- var taskInfo = event.context;
- this.set("parentView.isLogWrapHidden", false);
- if ($(".task-detail-log-clipboard").length) {
- this.destroyClipBoard();
- }
- this.set("parentView.isHostListHidden", true);
- this.set("parentView.isTaskListHidden", true);
- this.set('openedTaskId', taskInfo.id);
- this.switchLevel("TASK_DETAILS");
- $(".modal").scrollTop(0);
- $(".modal-body").scrollTop(0);
- },
- /**
- * Onclick event for copy to clipboard button
- *
- * @method textTrigger
- */
- textTrigger: function () {
- $(".task-detail-log-clipboard").length ? this.destroyClipBoard() : this.createClipBoard();
- },
- /**
- * Create Clip Board
- *
- * @method createClipBoard
- */
- createClipBoard: function () {
- var isLogComponentActive = this.get('hostComponentLogs').someProperty('isActive', true),
- logElement = isLogComponentActive ? $('.log-component-tab.active .log-tail-content'): $(".task-detail-log-maintext"),
- logElementRect = logElement[0].getBoundingClientRect(),
- clipBoardContent = this.get('clipBoardContent');
- $(".task-detail-log-clipboard-wrap").html('<textarea class="task-detail-log-clipboard"></textarea>');
- $(".task-detail-log-clipboard")
- .html(isLogComponentActive ? this.get('clipBoardContent') : "stderr: \n" + $(".stderr").html() + "\n stdout:\n" + $(".stdout").html())
- .css('display', 'block')
- .width(logElementRect.width)
- .height(isLogComponentActive ? logElement[0].scrollHeight : logElementRect.height)
- .select();
- this.set('isClipBoardActive', true);
- },
- /**
- * Destroy Clip Board
- *
- * @method destroyClipBoard
- */
- destroyClipBoard: function () {
- var logElement = this.get('hostComponentLogs').someProperty('isActive', true) ? $('.log-component-tab.active .log-tail-content'): $(".task-detail-log-maintext");
- $(".task-detail-log-clipboard").remove();
- logElement.css("display", "block");
- this.set('isClipBoardActive', false);
- },
- isLogSearchInstalled: function() {
- return App.Service.find().someProperty('serviceName', 'LOGSEARCH');
- }.property(),
- /**
- * Host component logs associated with selected component on 'TASK_DETAILS' level.
- *
- * @property {object[]}
- */
- hostComponentLogs: function() {
- var relationType,
- componentName,
- hostName,
- logFile,
- linkTailTpl = '?host_name={0}&file_name={1}&component_name={2}',
- self = this;
- if (this.get('openedTask.id')) {
- relationType = this._determineRoleRelation(this.get('openedTask'));
- if (relationType.type === 'component') {
- hostName = this.get('currentHost.name');
- componentName = relationType.value;
- return App.HostComponentLog.find()
- .filterProperty('hostComponent.host.hostName', hostName)
- .filterProperty('hostComponent.componentName', componentName)
- .reduce(function(acc, item, index) {
- var serviceName = item.get('hostComponent.service.serviceName'),
- logComponentName = item.get('name'),
- componentHostName = item.get('hostComponent.host.hostName');
- acc.pushObjects(item.get('logFileNames').map(function(logFileName, idx) {
- var tabClassName = logComponentName + '_' + index + '_' + idx;
- return Em.Object.create({
- hostName: componentHostName,
- logComponentName: logComponentName,
- fileName: logFileName,
- tabClassName: tabClassName,
- tabClassNameSelector: '.' + tabClassName,
- displayedFileName: fileUtils.fileNameFromPath(logFileName),
- linkTail: linkTailTpl.format(hostName, logFileName, logComponentName),
- isActive: false
- });
- }));
- return acc;
- }, []);
- }
- }
- return [];
- }.property('openedTaskId', 'isLevelLoaded'),
- /**
- * Determines if there are component logs for selected component within 'TASK_DETAILS' level.
- *
- * @property {boolean}
- */
- hostComponentLogsExists: function() {
- return this.get('isLogSearchInstalled') && !!this.get('hostComponentLogs.length') && this.get('parentView.isOpen');
- }.property('hostComponentLogs.length', 'isLogSearchInstalled', 'parentView.isOpen'),
- /**
- * Minimum required content to embed in App.LogTailView. This property observes current active host component log.
- *
- * @property {object}
- */
- logTailViewContent: function() {
- if (!this.get('hostComponentLog')) {
- return null;
- }
- return Em.Object.create({
- hostName: this.get('currentHost.name'),
- logComponentName: this.get('hostComponentLog.name')
- });
- }.property('hostComponentLogs.@each.isActive'),
- logTailView: App.LogTailView.extend({
- isActiveDidChange: function() {
- var self = this;
- if (this.get('content.isActive') === false) return;
- setTimeout(function() {
- self.scrollToBottom();
- self.storeToClipBoard();
- }, 500);
- }.observes('content.isActive'),
- logRowsLengthDidChange: function() {
- if (!this.get('content.isActive') || this.get('state') === 'destroyed') return;
- this.storeToClipBoard();
- }.observes('logRows.length'),
- /**
- * Stores log content to use for clip board.
- */
- storeToClipBoard: function() {
- this.get('parentView').set('clipBoardContent', this.get('logRows').map(function(i) {
- return i.get('logtimeFormatted') + ' ' + i.get('level') + ' ' + i.get('logMessage');
- }).join('\n'));
- }
- }),
- setActiveLogTab: function(e) {
- var content = e.context;
- this.set('clipBoardContent', null);
- this.get('hostComponentLogs').without(content).setEach('isActive', false);
- if (this.get('isClipBoardActive')) {
- this.destroyClipBoard();
- }
- content.set('isActive', true);
- },
- setActiveTaskLogTab: function() {
- this.set('clipBoardContent', null);
- this.get('hostComponentLogs').setEach('isActive', false);
- if (this.get('isClipBoardActive')) {
- this.destroyClipBoard();
- }
- }
- });
|