blob: 6bb00e88d8ded7a000c7086d51401d467972ca60 [file] [log] [blame]
/**
* 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');
App.Poll = Em.Object.extend(App.ReloadPopupMixin, {
name: '',
stage: '',
label: '',
isVisible: true,
isStarted: false,
isPolling: true,
clusterName: null,
requestId: null,
temp: false,
progress: 0,
url: null,
testUrl: null,
data: null,
isError: false,
isSuccess: false,
POLL_INTERVAL: 4000,
polledData: [],
numPolls: 0,
mockDataPrefix: '/data/wizard/deploy/5_hosts',
currentTaskId: null,
barWidth: Em.computed.format('width: {0}%;', 'progress'),
isCompleted: Em.computed.or('isError', 'isSuccess'),
showLink: Em.computed.or('isPolling', 'isStarted'),
start: function () {
if (Em.isNone(this.get('requestId'))) {
this.setRequestId();
} else {
this.startPolling();
}
},
setRequestId: function () {
if (App.get('testMode')) {
this.set('requestId', '1');
this.doPolling();
return;
}
var self = this;
var url = this.get('url');
var method = 'PUT';
var data = this.get('data');
$.ajax({
type: method,
url: url,
data: data,
dataType: 'text',
timeout: App.timeout,
success: function (data) {
var jsonData = jQuery.parseJSON(data);
if (Em.isNone(jsonData)) {
self.set('isSuccess', true);
self.set('isError', false);
} else {
var requestId = Em.get(jsonData, 'Requests.id');
self.set('requestId', requestId);
self.doPolling();
}
},
error: function () {
self.set('isError', true);
self.set('isSuccess', false);
},
statusCode: require('data/statusCodes')
});
},
/**
* set current task id and send request
* @param taskId
*/
updateTaskLog: function (taskId) {
this.set('currentTaskId', taskId);
this.pollTaskLog();
},
doPolling: function () {
if (!Em.isNone(this.get('requestId'))) {
this.startPolling();
}
},
/**
* server call to obtain task logs
*/
pollTaskLog: function () {
if (!Em.isNone(this.get('currentTaskId'))) {
App.ajax.send({
name: 'background_operations.get_by_task',
sender: this,
data: {
requestId: this.get('requestId'),
taskId: this.get('currentTaskId')
},
success: 'pollTaskLogSuccessCallback'
});
}
},
/**
* update logs of current task
* @param data
*/
pollTaskLogSuccessCallback: function (data) {
var currentTask = this.get('polledData').findProperty('Tasks.id', data.Tasks.id);
currentTask.Tasks.stdout = data.Tasks.stdout;
currentTask.Tasks.stderr = data.Tasks.stderr;
Em.propertyDidChange(this, 'polledData');
},
/**
* start polling operation data
* @return {Boolean}
*/
startPolling: function () {
if (Em.isNone(this.get('requestId'))) return false;
this.pollTaskLog();
App.ajax.send({
name: 'background_operations.get_by_request',
sender: this,
data: {
requestId: this.get('requestId'),
callback: this.startPolling
},
success: 'reloadSuccessCallback',
error: 'reloadErrorCallback'
});
return true;
},
reloadSuccessCallback: function (data) {
var self = this;
var result = this.parseInfo(data);
this._super();
if (!result) {
window.setTimeout(function () {
self.startPolling();
}, this.POLL_INTERVAL);
}
},
reloadErrorCallback: function (request, ajaxOptions, error, opt, params) {
this._super(request, ajaxOptions, error, opt, params);
if (request.status && !this.get('isSuccess')) {
this.set('isError', true);
}
},
stopPolling: function () {
//this.set('isSuccess', true);
},
replacePolledData: function (polledData) {
var currentTaskId = this.get('currentTaskId');
if (!Em.isNone(currentTaskId)) {
var task = this.get('polledData').findProperty('Tasks.id', currentTaskId);
var currentTask = polledData.findProperty('Tasks.id', currentTaskId);
if (task && currentTask) {
currentTask.Tasks.stdout = task.Tasks.stdout;
currentTask.Tasks.stderr = task.Tasks.stderr;
}
}
this.set('polledData', polledData);
},
calculateProgressByTasks: function (tasksData) {
var queuedTasks = tasksData.filterProperty('Tasks.status', 'QUEUED').length;
var completedTasks = tasksData.filter(function (task) {
return ['COMPLETED', 'FAILED', 'ABORTED', 'TIMEDOUT'].contains(task.Tasks.status);
}).length;
var inProgressTasks = tasksData.filterProperty('Tasks.status', 'IN_PROGRESS').length;
return Math.ceil(((queuedTasks * 0.09) + (inProgressTasks * 0.35) + completedTasks ) / tasksData.length * 100)
},
isPollingFinished: function (polledData) {
var runningTasks;
runningTasks = polledData.filterProperty('Tasks.status', 'QUEUED').length;
runningTasks += polledData.filterProperty('Tasks.status', 'IN_PROGRESS').length;
runningTasks += polledData.filterProperty('Tasks.status', 'PENDING').length;
if (runningTasks === 0) {
if (polledData.everyProperty('Tasks.status', 'COMPLETED')) {
this.set('isSuccess', true);
this.set('isError', false);
} else if (polledData.someProperty('Tasks.status', 'FAILED') || polledData.someProperty('Tasks.status', 'TIMEDOUT') || polledData.someProperty('Tasks.status', 'ABORTED')) {
this.set('isSuccess', false);
this.set('isError', true);
}
return true;
} else {
return false;
}
},
parseInfo: function (polledData) {
var tasksData = polledData.tasks;
var requestId = this.get('requestId');
if (polledData.Requests && !Em.isNone(polledData.Requests.id) && polledData.Requests.id != requestId) {
// We don't want to use non-current requestId's tasks data to
// determine the current install status.
// Also, we don't want to keep polling if it is not the
// current requestId.
return false;
}
this.replacePolledData(tasksData);
var totalProgress = this.calculateProgressByTasks(tasksData);
this.set('progress', totalProgress.toString());
return this.isPollingFinished(tasksData);
}
});