blob: aaca72ddffb1231c7eb2010531572f47cd96df3c [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.HighAvailabilityProgressPageController = App.HighAvailabilityWizardController.extend({
name: 'highAvailabilityProgressPageController',
status: 'IN_PROGRESS',
tasks: [],
commands: [],
currentRequestIds: [],
logs: [],
currentTaskId: null,
POLL_INTERVAL: 4000,
isSubmitDisabled: true,
serviceTimestamp: null,
isRollback: false,
loadStep: function () {
console.warn('func: loadStep');
this.clearStep();
this.loadTasks();
this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
this.onTaskStatusChange();
},
clearStep: function () {
console.warn('func: clearStep');
this.set('isSubmitDisabled', true);
this.set('tasks', []);
this.set('logs', []);
this.set('currentRequestIds', []);
var commands = this.get('commands');
var currentStep = App.router.get('highAvailabilityWizardController.currentStep');
for (var i = 0; i < commands.length; i++) {
this.get('tasks').pushObject(Ember.Object.create({
title: Em.I18n.t('admin.highAvailability.wizard.step' + currentStep + '.task' + i + '.title'),
status: 'PENDING',
id: i,
command: commands[i],
showRetry: false,
showRollback: false,
name: Em.I18n.t('admin.highAvailability.wizard.step' + currentStep + '.task' + i + '.title'),
displayName: Em.I18n.t('admin.highAvailability.wizard.step' + currentStep + '.task' + i + '.title'),
progress: 0,
isRunning: false,
hosts: []
}));
}
},
services: function(){
return this.get('tasks');
}.property('tasks'),
loadTasks: function () {
console.warn('func: loadTasks');
var self = this;
var loadedStauses = this.get('content.tasksStatuses');
var loadedLogs = this.get('content.logs');
if (loadedStauses && loadedLogs && loadedStauses.length === this.get('tasks').length) {
this.get('tasks').forEach(function(task,i){
self.setTaskStatus(task.get('id'), loadedStauses[i]);
self.restoreTaskLog(task.get('id'), loadedLogs[i]);
});
if (loadedStauses.contains('IN_PROGRESS')) {
var curTaskId = this.get('tasks')[loadedStauses.indexOf('IN_PROGRESS')].get('id');
this.set('currentRequestIds', this.get('content.requestIds'));
this.set('currentTaskId', curTaskId);
this.doPolling();
}else if (loadedStauses.contains('QUEUED')){
var curTaskId = this.get('tasks')[loadedStauses.indexOf('QUEUED')].get('id');
this.set('currentTaskId', curTaskId);
this.runTask(curTaskId);
}
}
},
setTaskStatus: function (taskId, status) {
console.warn('func: setTaskStatus');
this.get('tasks').findProperty('id', taskId).set('status', status);
},
restoreTaskLog: function (taskId, log) {
console.warn('func: restoreTaskLog');
this.get('tasks').findProperty('id', taskId).set('hosts', log);
},
setTaskLogs: function (taskId, tasks) {
console.warn('func: setTaskLogs');
var hosts = [];
var uniqHosts = tasks.mapProperty('Tasks.host_name').uniq();
uniqHosts.forEach(function (host) {
var curHostTasks = tasks.filterProperty('Tasks.host_name', host);
hosts.push(
{
name: host,
publicName: host,
logTasks: curHostTasks
}
);
});
this.get('tasks').findProperty('id', taskId).set('hosts', hosts);
this.set('serviceTimestamp', new Date().getTime());
},
retryTask: function () {
console.warn('func: retryTask');
var task = this.get('tasks').findProperty('status', 'FAILED');
task.set('showRetry', false);
task.set('showRollback', false);
task.set('status', 'PENDING');
},
manualRollback: function () {
console.warn('func: manualRollback');
App.ModalPopup.show({
header: Em.I18n.t('admin.highAvailability.confirmRollbackHeader'),
primary: Em.I18n.t('yes'),
showCloseButton: false,
onPrimary: function () {
var controller = App.router.get('highAvailabilityWizardController');
controller.clearTasksData();
controller.clearStorageData();
controller.setCurrentStep('1');
App.router.get('updateController').set('isWorking', true);
App.clusterStatus.setClusterStatus({
clusterName: App.router.get('content.cluster.name'),
clusterState: 'HIGH_AVAILABILITY_DISABLED',
wizardControllerName: App.router.get('highAvailabilityRollbackController.name'),
localdb: App.db.data
});
this.hide();
App.router.transitionTo('main.admin.index');
location.reload();
},
secondary : Em.I18n.t('no'),
onSecondary: function(){
this.hide();
},
bodyClass: Ember.View.extend({
template: Ember.Handlebars.compile( Em.I18n.t('admin.highAvailability.confirmManualRollbackBody'))
})
});
},
rollback: function () {
console.warn('func: rollback');
var task = this.get('tasks').findProperty('status', 'FAILED');
App.router.get(this.get('content.controllerName')).saveFailedTask(task);
App.ModalPopup.show({
header: Em.I18n.t('admin.highAvailability.confirmRollbackHeader'),
primary: Em.I18n.t('common.confirm'),
showCloseButton: false,
onPrimary: function () {
App.router.get('highAvailabilityWizardController').clearTasksData();
App.router.transitionTo('main.admin.highAvailabilityRollback');
this.hide();
},
secondary : Em.I18n.t('common.cancel'),
onSecondary: function(){
this.hide();
},
body: Em.I18n.t('admin.highAvailability.confirmRollbackBody')
});
},
onTaskStatusChange: function () {
console.warn('func: onTaskStatusChange1');
if (!this.get('tasks').someProperty('status', 'IN_PROGRESS') && !this.get('tasks').someProperty('status', 'QUEUED') && !this.get('tasks').someProperty('status', 'FAILED')) {
var nextTask = this.get('tasks').findProperty('status', 'PENDING');
if (nextTask) {
console.warn('func: onTaskStatusChange2');
this.set('status', 'IN_PROGRESS');
this.setTaskStatus(nextTask.get('id'), 'QUEUED');
this.set('currentTaskId', nextTask.get('id'));
this.runTask(nextTask.get('id'));
} else {
console.warn('func: onTaskStatusChange3');
this.set('status', 'COMPLETED');
this.set('isSubmitDisabled', false);
}
} else if (this.get('tasks').someProperty('status', 'FAILED')) {
console.warn('func: onTaskStatusChange4');
this.set('status', 'FAILED');
this.get('tasks').findProperty('status', 'FAILED').set('showRetry', true);
if(App.supports.autoRollbackHA){
this.get('tasks').findProperty('status', 'FAILED').set('showRollback', true);
}
}
this.get('tasks').filterProperty('status','COMPLETED').setEach('showRetry', false);
this.get('tasks').filterProperty('status','COMPLETED').setEach('showRollback', false);
var statuses = this.get('tasks').mapProperty('status');
var logs = this.get('tasks').mapProperty('hosts');
var requestIds = this.get('currentRequestIds');
console.warn('func: onTaskStatusChange5',statuses, logs, requestIds);
App.router.get(this.get('content.controllerName')).saveTasksStatuses(statuses);
App.router.get(this.get('content.controllerName')).saveRequestIds(requestIds);
App.router.get(this.get('content.controllerName')).saveLogs(logs);
App.clusterStatus.setClusterStatus({
clusterName: this.get('content.cluster.name'),
clusterState: 'HIGH_AVAILABILITY_DEPLOY',
wizardControllerName: this.get('content.controllerName'),
localdb: App.db.data
});
},
/*
run command of appropriate task
*/
runTask: function (taskId) {
console.warn('func: runTask',taskId);
this[this.get('tasks').findProperty('id', taskId).get('command')]();
},
onTaskError: function () {
console.warn('func: onTaskError');
this.setTaskStatus(this.get('currentTaskId'), 'FAILED');
},
onTaskCompleted: function () {
console.warn('func: onTaskCompleted');
this.setTaskStatus(this.get('currentTaskId'), 'COMPLETED');
},
createComponent: function (componentName, hostName) {
console.warn('func: createComponent');
if (!(hostName instanceof Array)) {
hostName = [hostName];
}
var hostComponents = [];
for (var i = 0; i < hostName.length; i++) {
hostComponents = App.HostComponent.find().filterProperty('componentName', componentName);
if (!hostComponents.length || !hostComponents.mapProperty('host.hostName').contains(hostName[i])) {
App.ajax.send({
name: 'admin.high_availability.create_component',
sender: this,
data: {
hostName: hostName[i],
componentName: componentName,
taskNum: hostName.length
},
success: 'onCreateComponent',
error: 'onTaskError'
});
} else {
var taskNum = hostName.length;
this.installComponent(componentName, hostName[i], taskNum);
}
}
},
onCreateComponent: function () {
console.warn('func: onCreateComponent');
var hostName = arguments[2].hostName;
var componentName = arguments[2].componentName;
var taskNum = arguments[2].taskNum;
this.installComponent(componentName, hostName, taskNum);
},
installComponent: function (componentName, hostName, taskNum) {
console.warn('func: installComponent');
if (!(hostName instanceof Array)) {
hostName = [hostName];
}
for (var i = 0; i < hostName.length; i++) {
App.ajax.send({
name: 'admin.high_availability.install_component',
sender: this,
data: {
hostName: hostName[i],
componentName: componentName,
displayName: App.format.role(componentName),
taskNum: taskNum || hostName.length
},
success: 'startPolling',
error: 'onTaskError'
});
}
},
startComponent: function (componentName, hostName) {
console.warn('func: startComponent');
if (!(hostName instanceof Array)) {
hostName = [hostName];
}
for (var i = 0; i < hostName.length; i++) {
App.ajax.send({
name: 'admin.high_availability.start_component',
sender: this,
data: {
hostName: hostName[i],
componentName: componentName,
displayName: App.format.role(componentName),
taskNum: hostName.length
},
success: 'startPolling',
error: 'onTaskError'
});
}
},
startPolling: function (data) {
if (data) {
console.warn('func: startPolling1');
this.get('currentRequestIds').push(data.Requests.id);
var tasksCount = arguments[2].taskNum || 1;
if (tasksCount === this.get('currentRequestIds').length) {
console.warn('func: startPolling2');
this.doPolling();
}
} else {
console.warn('func: startPolling3');
this.onTaskCompleted();
}
},
doPolling: function () {
console.warn('func: doPolling');
this.setTaskStatus(this.get('currentTaskId'), 'IN_PROGRESS');
var requestIds = this.get('currentRequestIds');
for (var i = 0; i < requestIds.length; i++) {
App.ajax.send({
name: 'admin.high_availability.polling',
sender: this,
data: {
requestId: requestIds[i]
},
success: 'parseLogs',
error: 'onTaskError'
});
}
},
parseLogs: function (logs) {
console.warn('func: parseLogs');
this.get('logs').push(logs.tasks);
if (this.get('currentRequestIds').length === this.get('logs').length) {
var tasks = [];
this.get('logs').forEach(function (logs) {
tasks.pushObjects(logs);
}, this);
var self = this;
var currentTaskId = this.get('currentTaskId');
this.setTaskLogs(currentTaskId, tasks);
if (!tasks.someProperty('Tasks.status', 'PENDING') && !tasks.someProperty('Tasks.status', 'QUEUED') && !tasks.someProperty('Tasks.status', 'IN_PROGRESS')) {
this.set('currentRequestIds', []);
if (tasks.someProperty('Tasks.status', 'FAILED') || tasks.someProperty('status', 'TIMEDOUT') || tasks.someProperty('status', 'ABORTED')) {
this.setTaskStatus(currentTaskId, 'FAILED');
} else {
this.setTaskStatus(currentTaskId, 'COMPLETED');
}
} else {
var actionsPerHost = tasks.length;
var completedActions = tasks.filterProperty('Tasks.status', 'COMPLETED').length
+ tasks.filterProperty('Tasks.status', 'FAILED').length
+ tasks.filterProperty('Tasks.status', 'ABORTED').length
+ tasks.filterProperty('Tasks.status', 'TIMEDOUT').length;
var queuedActions = tasks.filterProperty('Tasks.status', 'QUEUED').length;
var inProgressActions = tasks.filterProperty('Tasks.status', 'IN_PROGRESS').length;
var progress = Math.ceil(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / actionsPerHost * 100);
this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
window.setTimeout(function () {
self.doPolling()
}, self.POLL_INTERVAL);
}
this.set('logs', []);
}
},
done: function () {
if (!this.get('isSubmitDisabled')) {
this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
App.router.send('next');
}
}
});