<commit_before>/**
 * 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');

/**
 * Mixin for wizard controller for showing command progress on wizard pages
 * This should
 * @type {Ember.Mixin}
 */
App.wizardProgressPageControllerMixin = Em.Mixin.create({
  controllerName: '',
  clusterDeployState: 'WIZARD_DEPLOY',
  status: 'IN_PROGRESS',
  tasks: [],
  commands: [],
  currentRequestIds: [], //todo: replace with using requestIds from tasks
  logs: [],
  currentTaskId: null,
  POLL_INTERVAL: 4000,
  isSubmitDisabled: true,
  isBackButtonDisabled: true,
  stages: [],
  currentPageRequestId: null,
  isSingleRequestPage: false,
  isCommandLevelRetry: function () {
    return !this.get('isSingleRequestPage');
  }.property('isSingleRequestPage'),
  showRetry: false,
  /**
   * Show whether tasks data was loaded
   * @type {Boolean}
   */
  isLoading: false,

  k: Em.K,
  /**
   *  tasksMessagesPrefix should be overloaded by any controller including the mixin
   */
  tasksMessagesPrefix: '',

  loadStep: function () {
    this.clearStep();
    var self = this;
    if (!self.isSingleRequestPage) {
      this.initStep();
    } else {
      var requestIds = this.get('content.tasksRequestIds');
      var currentRequestId = requestIds && requestIds[0][0];
      if (!currentRequestId) {
        this.set('isLoaded', false);
        this.submitRequest();
      } else {
        self.set('currentPageRequestId', currentRequestId);
        self.doPollingForPageRequest();
      }
    }
  },

  initStep: function () {
    this.initializeTasks();
    if (!this.isSingleRequestPage) {
      this.loadTasks();
    }
    this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
    if (this.isSingleRequestPage) {
      var dfd = $.Deferred();
      var dfdObject = {
        deferred: dfd,
        isJqueryPromise: true
      };
      this.onTaskStatusChange(dfdObject);
      return dfd.promise();
    } else {
      this.onTaskStatusChange();
    }
  },

  clearStep: function () {
    this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
    this.set('isSubmitDisabled', true);
    this.set('isBackButtonDisabled', true);
    this.set('tasks', []);
    this.set('currentRequestIds', []);
    this.set('isLoaded', false);
  },

  /**
   * Clear stages info for single page request.
   */
  clearStage: function() {
    this.setDBProperty('tasksRequestIds', null);
    this.setDBProperty('tasksStatuses', null);
    this.set('showRetry', false);
    this.set('content.tasksRequestIds', null);
    this.set('content.tasksStatuses', null);
    this.set('content.currentTaskId', null);
    this.get('stages').clear();
  },

  retry: function () {
    this.set('showRetry', false);
    this.get('tasks').setEach('status','PENDING');
    this.loadStep();
  },

  submitRequest: function () {
    return App.ajax.send({
      name: this.get('request.ajaxName'),
      data: this.get('request.ajaxData'),
      sender: this,
      error: 'onSingleRequestError',
      success: 'submitRequestSuccess',
      kdcCancelHandler: 'failTaskOnKdcCheck'
    });
  },

  submitRequestSuccess: function(data, result, request) {
    if (data) {
      this.set('currentPageRequestId', data.Requests.id);
      this.doPollingForPageRequest();
    } else {
      //Step has been successfully completed
      if (request.status === 200) {
        this.set('status', 'COMPLETED');
        this.set('isSubmitDisabled', false);
        this.set('isLoaded', true);
      }
    }
  },

  failTaskOnKdcCheck: function() {
    this.set('status', 'FAILED');
    this.set('isLoaded', true);
    this.set('showRetry', true);
  },

  doPollingForPageRequest: function () {
    App.ajax.send({
      name: 'admin.poll.kerberize.cluster.request',
      sender: this,
      data: {
        requestId: this.get('currentPageRequestId')
      },
      success: 'initializeStages'
    });
  },

  initializeStages: function (data) {
    var self = this;
    var stages = [];
    this.set('logs', []);
    data.stages.forEach(function (_stage) {
      stages.pushObject(Em.Object.create(_stage.Stage));
    }, this);
    if (!this.get('stages').length) {
      this.get('stages').pushObjects(stages);
      this.initStep().done(function(){
        self.updatePageWithPolledData(data);
      });
    } else {
      this.updatePageWithPolledData(data);
    }
  },

  updatePageWithPolledData: function(data) {
    // If all tasks completed no need to update each task status.
    // Preferable to skip polling of data for completed tasks after page refresh.
    if (this.get('status') === 'COMPLETED') return;
    var self = this;
    var tasks = [];
    var currentPageRequestId = this.get('currentPageRequestId');
    var currentTaskId = this.get('currentTaskId');
    var currentTask = this.get('tasks').findProperty('id', currentTaskId);
    var currentStage =  data.stages.findProperty('Stage.stage_id', currentTask.get('stageId'));
    var tasksInCurrentStage =  currentStage.tasks;
    this.set('logs',tasksInCurrentStage);

    this.setRequestIds(this.get('currentTaskId'), [this.get('currentPageRequestId')]);

    if (!tasksInCurrentStage.someProperty('Tasks.status', 'PENDING') && !tasksInCurrentStage.someProperty('Tasks.status', 'QUEUED') && !tasksInCurrentStage.someProperty('Tasks.status', 'IN_PROGRESS')) {
      this.set('currentRequestIds', []);
      if (tasksInCurrentStage.someProperty('Tasks.status', 'FAILED') || tasksInCurrentStage.someProperty('Tasks.status', 'TIMEDOUT') || tasksInCurrentStage.someProperty('Tasks.status', 'ABORTED')) {
        this.setTaskStatus(currentTaskId, 'FAILED');
      } else {
        this.setTaskStatus(currentTaskId, 'COMPLETED');
      }
    } else {
      var completedActions = tasksInCurrentStage.filterProperty('Tasks.status', 'COMPLETED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'FAILED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'ABORTED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'TIMEDOUT').length;
      var queuedActions = tasksInCurrentStage.filterProperty('Tasks.status', 'QUEUED').length;
      var inProgressActions = tasksInCurrentStage.filterProperty('Tasks.status', 'IN_PROGRESS').length;
      var progress = completedActions == this.get('tasks.length') ? 100 : Math.floor(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / tasksInCurrentStage.length * 100);
      this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
    }

    // start polling if current step status not completed or failed
    if (!(this.get('status') === 'COMPLETED' && this.get('status') === 'FAILED')) {
      window.setTimeout(function () {
        self.doPollingForPageRequest();
      }, self.POLL_INTERVAL);
    }
  },

  initializeTasks: function () {
    var self = this;
    var commands = this.isSingleRequestPage ? this.get('stages') : this.get('commands');
    var currentStep = App.router.get(this.get('content.controllerName') + '.currentStep');
    var tasksMessagesPrefix = this.get('tasksMessagesPrefix');
    // check that all stages have been completed for single request type
    var allStagesCompleted = commands.everyProperty('status', 'COMPLETED');
    for (var i = 0; i < commands.length; i++) {
      this.get('tasks').pushObject(Ember.Object.create({
        title: self.isSingleRequestPage ? commands[i].get('context') : Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
        // set COMPLETED status for task if all stages completed successfully
        status: allStagesCompleted ? 'COMPLETED' : 'PENDING',
        id: i,
        stageId: self.isSingleRequestPage ? commands[i].get('stage_id') : null,
        command: self.isSingleRequestPage ? 'k' : commands[i],
        showRetry: false,
        showRollback: false,
        name: self.isSingleRequestPage ? commands[i].get('context') : Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),<commit_msg>AMBARI-9925. Kerberos Wizard: Step 6. Timedout task continue pending(onechiporenko)<commit_after>/**
 * 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');

/**
 * Mixin for wizard controller for showing command progress on wizard pages
 * This should
 * @type {Ember.Mixin}
 */
App.wizardProgressPageControllerMixin = Em.Mixin.create({
  controllerName: '',
  clusterDeployState: 'WIZARD_DEPLOY',
  status: 'IN_PROGRESS',
  tasks: [],
  commands: [],
  currentRequestIds: [], //todo: replace with using requestIds from tasks
  logs: [],
  currentTaskId: null,
  POLL_INTERVAL: 4000,
  isSubmitDisabled: true,
  isBackButtonDisabled: true,
  stages: [],
  /**
   * List of statuses that inform about the end of request progress.
   * @type {String[]}
   */
  completedStatuses: ['COMPLETED', 'FAILED', 'TIMEDOUT', 'ABORTED'],
  currentPageRequestId: null,
  isSingleRequestPage: false,
  isCommandLevelRetry: function () {
    return !this.get('isSingleRequestPage');
  }.property('isSingleRequestPage'),
  showRetry: false,
  /**
   * Show whether tasks data was loaded
   * @type {Boolean}
   */
  isLoading: false,

  k: Em.K,
  /**
   *  tasksMessagesPrefix should be overloaded by any controller including the mixin
   */
  tasksMessagesPrefix: '',

  loadStep: function () {
    this.clearStep();
    var self = this;
    if (!self.isSingleRequestPage) {
      this.initStep();
    } else {
      var requestIds = this.get('content.tasksRequestIds');
      var currentRequestId = requestIds && requestIds[0][0];
      if (!currentRequestId) {
        this.set('isLoaded', false);
        this.submitRequest();
      } else {
        self.set('currentPageRequestId', currentRequestId);
        self.doPollingForPageRequest();
      }
    }
  },

  initStep: function () {
    this.initializeTasks();
    if (!this.isSingleRequestPage) {
      this.loadTasks();
    }
    this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
    if (this.isSingleRequestPage) {
      var dfd = $.Deferred();
      var dfdObject = {
        deferred: dfd,
        isJqueryPromise: true
      };
      this.onTaskStatusChange(dfdObject);
      return dfd.promise();
    } else {
      this.onTaskStatusChange();
    }
  },

  clearStep: function () {
    this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
    this.set('isSubmitDisabled', true);
    this.set('isBackButtonDisabled', true);
    this.set('tasks', []);
    this.set('currentRequestIds', []);
    this.set('isLoaded', false);
  },

  /**
   * Clear stages info for single page request.
   */
  clearStage: function() {
    this.setDBProperty('tasksRequestIds', null);
    this.setDBProperty('tasksStatuses', null);
    this.set('showRetry', false);
    this.set('content.tasksRequestIds', null);
    this.set('content.tasksStatuses', null);
    this.set('content.currentTaskId', null);
    this.get('stages').clear();
  },

  retry: function () {
    this.set('showRetry', false);
    this.get('tasks').setEach('status','PENDING');
    this.loadStep();
  },

  submitRequest: function () {
    return App.ajax.send({
      name: this.get('request.ajaxName'),
      data: this.get('request.ajaxData'),
      sender: this,
      error: 'onSingleRequestError',
      success: 'submitRequestSuccess',
      kdcCancelHandler: 'failTaskOnKdcCheck'
    });
  },

  submitRequestSuccess: function(data, result, request) {
    if (data) {
      this.set('currentPageRequestId', data.Requests.id);
      this.doPollingForPageRequest();
    } else {
      //Step has been successfully completed
      if (request.status === 200) {
        this.set('status', 'COMPLETED');
        this.set('isSubmitDisabled', false);
        this.set('isLoaded', true);
      }
    }
  },

  failTaskOnKdcCheck: function() {
    this.set('status', 'FAILED');
    this.set('isLoaded', true);
    this.set('showRetry', true);
  },

  doPollingForPageRequest: function () {
    App.ajax.send({
      name: 'admin.poll.kerberize.cluster.request',
      sender: this,
      data: {
        requestId: this.get('currentPageRequestId')
      },
      success: 'initializeStages'
    });
  },

  initializeStages: function (data) {
    var self = this;
    var stages = [];
    this.set('logs', []);
    data.stages.forEach(function (_stage) {
      stages.pushObject(Em.Object.create(_stage.Stage));
    }, this);
    if (!this.get('stages').length) {
      this.get('stages').pushObjects(stages);
      this.initStep().done(function(){
        self.updatePageWithPolledData(data);
      });
    } else {
      this.updatePageWithPolledData(data);
    }
  },

  updatePageWithPolledData: function(data) {
    // If all tasks completed no need to update each task status.
    // Preferable to skip polling of data for completed tasks after page refresh.
    if (this.get('status') === 'COMPLETED') return;
    var self = this;
    var tasks = [];
    var currentPageRequestId = this.get('currentPageRequestId');
    var currentTaskId = this.get('currentTaskId');
    var currentTask = this.get('tasks').findProperty('id', currentTaskId);
    var currentStage =  data.stages.findProperty('Stage.stage_id', currentTask.get('stageId'));
    var tasksInCurrentStage =  currentStage.tasks;
    this.set('logs',tasksInCurrentStage);

    this.setRequestIds(this.get('currentTaskId'), [this.get('currentPageRequestId')]);

    if (!tasksInCurrentStage.someProperty('Tasks.status', 'PENDING') && !tasksInCurrentStage.someProperty('Tasks.status', 'QUEUED') && !tasksInCurrentStage.someProperty('Tasks.status', 'IN_PROGRESS')) {
      this.set('currentRequestIds', []);
      if (tasksInCurrentStage.someProperty('Tasks.status', 'FAILED') || tasksInCurrentStage.someProperty('Tasks.status', 'TIMEDOUT') || tasksInCurrentStage.someProperty('Tasks.status', 'ABORTED')) {
        this.setTaskStatus(currentTaskId, 'FAILED');
      } else {
        this.setTaskStatus(currentTaskId, 'COMPLETED');
      }
    } else {
      var completedActions = tasksInCurrentStage.filterProperty('Tasks.status', 'COMPLETED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'FAILED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'ABORTED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'TIMEDOUT').length;
      var queuedActions = tasksInCurrentStage.filterProperty('Tasks.status', 'QUEUED').length;
      var inProgressActions = tasksInCurrentStage.filterProperty('Tasks.status', 'IN_PROGRESS').length;
      var progress = Math.floor(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / tasksInCurrentStage.length * 100);
      this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
    }

    // start polling if current request not completed
    if (!(this.get('completedStatuses').contains(this.get('status')))) {
      window.setTimeout(function () {
        self.doPollingForPageRequest();
      }, self.POLL_INTERVAL);
    }
  },

  initializeTasks: function () {
    var self = this;
    var commands = this.isSingleRequestPage ? this.get('stages') : this.get('commands');
    var currentStep = App.router.get(this.get('content.controllerName') + '.currentStep');
    var tasksMessagesPrefix = this.get('tasksMessagesPrefix');
    // check that all stages have been completed for single request type
    var allStagesCompleted = commands.everyProperty('status', 'COMPLETED');
    for (var i = 0; i < commands.length; i++) {
      this.get('tasks').pushObject(Ember.Object.create({
        title: self.isSingleRequestPage ? commands[i].get('context') : Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
        // set COMPLETED status for task if all stages completed successfully
        status: allStagesCompleted ? 'COMPLETED' : 'PENDING',
        id: i,
        stageId: self.isSingleRequestPage ? commands[i].get('stage_id') : null,
        command: self.isSingleRequestPage ? 'k' : commands[i],
        showRetry: false,
        showRollback: false,
        name: self.isSingleRequestPage ? commands[i].get('context') : Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
{'fraction_non_alphanumeric': 0.14018533167589559, 'fraction_numerical': 0.003503220702904283, 'mean_word_length': 3.5522119341563787, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4246820', 'n_tokens_mistral': 5262, 'n_tokens_neox': 5207, 'n_words': 1164}