From c4eb6515b1f04dde06453d0f06256dbc6fcfbd8c Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Thu, 29 Sep 2016 21:34:36 -0400 Subject: [PATCH] made status bar utilize completed jobs and started rudimentary event queue --- .../src/job-results/event-queue.service.js | 32 +++++++++++++++ .../src/job-results/job-results.controller.js | 41 +++++++++++++++---- .../src/job-results/job-results.route.js | 3 ++ .../src/job-results/job-results.service.js | 28 +++++++++++-- awx/ui/client/src/job-results/main.js | 9 +++- 5 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 awx/ui/client/src/job-results/event-queue.service.js diff --git a/awx/ui/client/src/job-results/event-queue.service.js b/awx/ui/client/src/job-results/event-queue.service.js new file mode 100644 index 0000000000..7d1e29c736 --- /dev/null +++ b/awx/ui/client/src/job-results/event-queue.service.js @@ -0,0 +1,32 @@ +/************************************************* +* Copyright (c) 2016 Ansible, Inc. +* +* All Rights Reserved +*************************************************/ + + +export default [function(){ + var val = { + queue: {}, + // munge the raw event from the backend into the event_queue's format + mungeEvent: function(event) { + event.processed = false; + return event; + }, + // reinitializes the event queue value for the job results page + initialize: function() { + val.queue = {}; + }, + // populates the event queue + populate: function(event) { + var mungedEvent = val.mungeEvent(event); + val.queue[event.id] = mungedEvent; + }, + // the event has been processed in the view and should be marked as + // completed in the queue + markProcessed: function(event) { + val.queue[event.id].processed = true; + } + }; + return val; +}]; diff --git a/awx/ui/client/src/job-results/job-results.controller.js b/awx/ui/client/src/job-results/job-results.controller.js index 69a9ac8056..9c81bda573 100644 --- a/awx/ui/client/src/job-results/job-results.controller.js +++ b/awx/ui/client/src/job-results/job-results.controller.js @@ -1,4 +1,22 @@ -export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', '$rootScope', function(jobData, jobDataOptions, jobLabels, $scope, ParseTypeChange, ParseVariableString, jobResultsService, $rootScope) { +export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', '$rootScope', 'eventQueue', function(jobData, jobDataOptions, jobLabels, $scope, ParseTypeChange, ParseVariableString, jobResultsService, $rootScope, eventQueue) { + // just putting the event queue on scope so it can be inspected in the + // console + $scope.event_queue = eventQueue.queue; + + var processEvent = function(event) { + // put the event in the queue + eventQueue.populate(event); + + if(event.event_name === "playbook_on_stats"){ + // get the data for populating the host status bar + $scope.count = jobResultsService + .getHostStatusBarCounts(event.event_data); + + // mark the event as processed in the queue; + eventQueue.markProcessed(event); + } + } + var getTowerLinks = function() { var getTowerLink = function(key) { if ($scope.job.related[key]) { @@ -69,20 +87,27 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeCh jobResultsService.cancelJob($scope.job); }; + // grab completed event data and process each event + jobResultsService.getEvents($scope.job) + .then(events => { + events.forEach(event => { + // get the name in the same format as the data + // coming over the websocket + event.event_name = event.event; + processEvent(event); + }); + }) + + // process incoming job events $rootScope.event_socket.on("job_events-" + $scope.job.id, function(data) { - if(data.event_name === "playbook_on_stats"){ - // get the data for populating the host status bar - $scope.count = jobResultsService - .getHostStatusBarCounts(data.event_data); - } + processEvent(data); }); + // process incoming job status changes $rootScope.$on('JobStatusChange-jobDetails', function(e, data) { if (parseInt(data.unified_job_id, 10) === parseInt($scope.job.id,10)) { $scope.job.status = data.status; } }); - - }]; diff --git a/awx/ui/client/src/job-results/job-results.route.js b/awx/ui/client/src/job-results/job-results.route.js index 5268acd0fa..023fa237d5 100644 --- a/awx/ui/client/src/job-results/job-results.route.js +++ b/awx/ui/client/src/job-results/job-results.route.js @@ -88,6 +88,9 @@ export default { } else { return true; } + }], + eventQueueInit: ['eventQueue', function(eventQueue) { + eventQueue.initialize(); }] }, templateUrl: templateUrl('job-results/job-results'), diff --git a/awx/ui/client/src/job-results/job-results.service.js b/awx/ui/client/src/job-results/job-results.service.js index 5e311ca579..76ee2bca94 100644 --- a/awx/ui/client/src/job-results/job-results.service.js +++ b/awx/ui/client/src/job-results/job-results.service.js @@ -5,10 +5,11 @@ *************************************************/ -export default ['Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', function (Prompt, $filter, Wait, Rest, $state, ProcessErrors) { +export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', function ($q, Prompt, $filter, Wait, Rest, $state, ProcessErrors) { var val = { getHostStatusBarCounts: function(event_data) { - var hosts = {}; + var hosts = {}, + hostsArr; // iterate over the event_data and populate an object with hosts // and their status data @@ -16,7 +17,7 @@ export default ['Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', // failed passes boolean not integer if (key === "failed") { // array of hosts from failed type - var hostsArr = Object.keys(event_data[key]); + hostsArr = Object.keys(event_data[key]); hostsArr.forEach(host => { if (!hosts[host]) { // host has not been added to hosts object @@ -28,7 +29,7 @@ export default ['Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', }); } else { // array of hosts from each type ("changed", "dark", etc.) - var hostsArr = Object.keys(event_data[key]); + hostsArr = Object.keys(event_data[key]); hostsArr.forEach(host => { if (!hosts[host]) { // host has not been added to hosts object @@ -72,6 +73,25 @@ export default ['Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', return count; }, + getEvents: function(job) { + var val = $q.defer(); + + Rest.setUrl(job.related.job_events); + Rest.get() + .success(function(data) { + val.resolve(data.results); + }) + .error(function(obj, status) { + ProcessErrors(null, obj, status, null, { + hdr: 'Error!', + msg: `Could not get job events. + Returned status: ${status}` + }); + val.reject(obj); + }); + + return val.promise; + }, deleteJob: function(job) { Prompt({ hdr: 'Delete Job', diff --git a/awx/ui/client/src/job-results/main.js b/awx/ui/client/src/job-results/main.js index 104ca76086..71f08b09be 100644 --- a/awx/ui/client/src/job-results/main.js +++ b/awx/ui/client/src/job-results/main.js @@ -4,15 +4,20 @@ * All Rights Reserved *************************************************/ +import hostStatusBar from './host-status-bar/main'; + import route from './job-results.route.js'; + import jobResultsService from './job-results.service'; -import hostStatusBarDirective from './host-status-bar/main'; +import eventQueueService from './event-queue.service'; + import durationFilter from './duration.filter'; export default - angular.module('jobResults', [hostStatusBarDirective.name]) + angular.module('jobResults', [hostStatusBar.name]) .run(['$stateExtender', function($stateExtender) { $stateExtender.addState(route); }]) .service('jobResultsService', jobResultsService) + .service('eventQueue', eventQueueService) .filter('duration', durationFilter);