diff --git a/awx/ui/static/js/system-tracking/data-services/fact-scan-data.service.js b/awx/ui/static/js/system-tracking/data-services/fact-scan-data.service.js index 7187a4078d..eb77caecad 100644 --- a/awx/ui/static/js/system-tracking/data-services/fact-scan-data.service.js +++ b/awx/ui/static/js/system-tracking/data-services/fact-scan-data.service.js @@ -6,13 +6,36 @@ export default ['Rest', 'GetBasePath', 'ProcessErrors', 'lodashAsPromised', function (Rest, GetBasePath, ProcessErrors, _) { + + function buildUrl (host_id, module, startDate, endDate) { + var url = GetBasePath('hosts') + host_id + '/fact_versions/', + params= [["module", module] , ['from', startDate.format()], ['to', endDate.format()]]; + + params = params.filter(function(p){ + return !_.isEmpty(p[1]); + }); + params = params.map(function(p){ + return p.join("="); + }).join("&"); + url = _.compact([url, params]).join("?"); + return url; + } + return { getHostFacts: function(host, moduleName, date, fetchScanNumber) { - var version =this.getVersion(host, moduleName, date.from, date.to, fetchScanNumber); + var getVersion = _.partial(this.getVersion, host, moduleName); var getFacts = this.getFacts; - return version + return getVersion(date.from, date.to, fetchScanNumber) + .then(function(versionData) { + if (_.isEmpty(versionData)) { + var retryStartDate = date.from.clone().subtract(1, 'year'); + return getVersion(retryStartDate, date.from, fetchScanNumber); + } else { + return versionData; + } + }) .then(function(versionData) { if (_.isEmpty(versionData)) { return { fact: [] }; @@ -37,18 +60,21 @@ function (Rest, GetBasePath, ProcessErrors, _) { }); }, - getVersion: function(host_id, module, startDate, endDate, fetchScanNumber){ + getVersion: function(versionParams){ //move the build url into getVersion and have the // parameters passed into this - var promise, - url = this.buildUrl(host_id, module, startDate, endDate); + var promise; + var hostId = versionParams.hostId; + var startDate = versionParams.dateRange.from; + var endDate = versionParams.dateRange.to; + var module = versionParams.moduleName; - fetchScanNumber = fetchScanNumber || 0; + var url = buildUrl(hostId, module, startDate, endDate); Rest.setUrl(url); promise = Rest.get(); - return promise.then(function(data) { - return data.data.results[fetchScanNumber]; + return promise.then(function(response) { + return response.data.results; }).catch(function (response) { ProcessErrors(null, response.data, response.status, null, { hdr: 'Error!', @@ -56,20 +82,6 @@ function (Rest, GetBasePath, ProcessErrors, _) { response.status }); }); - }, - - buildUrl: function(host_id, module, startDate, endDate){ - var url = GetBasePath('hosts') + host_id + '/fact_versions/', - params= [["module", module] , ['from', startDate.format()], ['to', endDate.format()]]; - - params = params.filter(function(p){ - return !_.isEmpty(p[1]); - }); - params = params.map(function(p){ - return p.join("="); - }).join("&"); - url = _.compact([url, params]).join("?"); - return url; } }; }]; diff --git a/awx/ui/static/js/system-tracking/data-services/get-data-for-comparison.factory.js b/awx/ui/static/js/system-tracking/data-services/get-data-for-comparison.factory.js index 42c8796181..8179085d22 100644 --- a/awx/ui/static/js/system-tracking/data-services/get-data-for-comparison.factory.js +++ b/awx/ui/static/js/system-tracking/data-services/get-data-for-comparison.factory.js @@ -7,8 +7,9 @@ export default [ 'factScanDataService', 'getModuleOptions', + 'resolveVersions', 'lodashAsPromised', - function(factScanDataService, getModuleOptions, _) { + function(factScanDataService, getModuleOptions, resolveVersions) { return function(hostIds, moduleName, leftDate, rightDate) { var moduleOptions; @@ -17,39 +18,40 @@ export default hostIds = hostIds.concat(hostIds[0]); } + var hostVersionParams = + [{ hostId: hostIds[0], + dateRange: leftDate, + moduleName: moduleName + }, + { hostId: hostIds[1], + dateRange: rightDate, + moduleName: moduleName + } + ]; + return getModuleOptions(hostIds[0]) .then(function(modules) { moduleOptions = modules; - return modules; - }).then(function() { - return hostIds; - }).thenMap(function(hostId, index) { - var date = leftDate; - var fetchScanNumber; - - if (index === 1) { - date = rightDate; - } else { - if (rightDate.from.isSame(leftDate.from, 'day')) { - fetchScanNumber = 1; - } - } - - var params = - [ hostId, - moduleName, - date, - fetchScanNumber + return hostVersionParams; + }).thenMap(function(versionParam) { + var versionWithRequest = + [ versionParam, + factScanDataService. + getVersion(versionParam) ]; - return params; - }).thenMap(function(params) { - var getHostFacts = - _.spread(factScanDataService.getHostFacts) - .bind(factScanDataService); - - return getHostFacts(params); - }).then(function(hostFacts) { + return versionWithRequest; + }).thenAll(function(versions) { + return resolveVersions(versions); + }, true) + .thenMap(function(versionData) { + if (versionData) { + return factScanDataService.getFacts(versionData); + } else { + return { fact: [] }; + } + }) + .thenAll(function(hostFacts) { return [moduleOptions, hostFacts]; }); }; diff --git a/awx/ui/static/js/system-tracking/data-services/resolve-versions.factory.js b/awx/ui/static/js/system-tracking/data-services/resolve-versions.factory.js new file mode 100644 index 0000000000..bf6898c34a --- /dev/null +++ b/awx/ui/static/js/system-tracking/data-services/resolve-versions.factory.js @@ -0,0 +1,75 @@ +function resolveVersions(service, _, results) { + + function transformToObjects(versionArray) { + + var converted = versionArray[0]; + converted.versions = versionArray[1]; + + return converted; + + } + + function resolveEmpties(result) { + if (_.isEmpty(result.versions)) { + var originalStartDate = result.dateRange.from; + result.dateRange.from = originalStartDate.clone().subtract(1, 'year'); + result.dateRange.to = originalStartDate; + return [result, service.getVersion(result)]; + } + + return [result, _.promise(result.versions)]; + } + + function resolveDuplicates(nonEmptyResults) { + var allSameHost = + _.every(nonEmptyResults, { 'hostId': nonEmptyResults[0].hostId }); + + if (allSameHost) { + var firstTimestamp = nonEmptyResults[0].versions[0].timestamp; + + var hostIdsWithDupes = + _(nonEmptyResults) + .pluck('versions[0]') + .filter('timestamp', firstTimestamp) + .map(function(version, index) { + return nonEmptyResults[index].hostId; + }) + .value(); + + if (hostIdsWithDupes.length === 1) { + return _.pluck(nonEmptyResults, 'versions[0]'); + } + + return nonEmptyResults.map(function(scan, index) { + var hasDupe = + _.include(hostIdsWithDupes, scan.hostId); + + if (hasDupe && index === 1) { + return scan.versions[1]; + } else { + return scan.versions[0]; + } + }); + + } else { + return _.pluck(nonEmptyResults, 'versions[0]'); + } + } + + return _(results) + .map(transformToObjects) + .map(resolveEmpties) + .thenAll(function(resolved) { + var versionObjects = resolved.map(transformToObjects); + return resolveDuplicates(versionObjects); + }, true) + .value(); +} + +export default + [ 'factScanDataService', + 'lodashAsPromised', + function(factScanDataService, lodash) { + return _.partial(resolveVersions, factScanDataService, lodash); + } + ]; diff --git a/awx/ui/static/js/system-tracking/main.js b/awx/ui/static/js/system-tracking/main.js index 3a42fd821e..c1e94bd617 100644 --- a/awx/ui/static/js/system-tracking/main.js +++ b/awx/ui/static/js/system-tracking/main.js @@ -8,6 +8,7 @@ import route from './system-tracking.route'; import factScanDataService from './data-services/fact-scan-data.service'; import getDataForComparison from './data-services/get-data-for-comparison.factory'; import getModuleOptions from './data-services/get-module-options.factory'; +import resolveVersions from './data-services/resolve-versions.factory'; import controller from './system-tracking.controller'; import stringOrDateFilter from './string-or-date.filter'; import shared from 'tower/shared/main'; @@ -23,6 +24,7 @@ export default .service('factScanDataService', factScanDataService) .factory('getDataForComparison', getDataForComparison) .factory('getModuleOptions', getModuleOptions) + .factory('resolveVersions', resolveVersions) .filter('stringOrDate', stringOrDateFilter) .controller('systemTracking', controller) .config(['$routeProvider', function($routeProvider) { diff --git a/awx/ui/static/js/system-tracking/system-tracking.controller.js b/awx/ui/static/js/system-tracking/system-tracking.controller.js index f6fca4ccde..223df0cade 100644 --- a/awx/ui/static/js/system-tracking/system-tracking.controller.js +++ b/awx/ui/static/js/system-tracking/system-tracking.controller.js @@ -24,8 +24,8 @@ function controller($rootScope, $scope.hostIds = $routeParams.hosts; $scope.inventory = $routeParams.model.inventory; - $scope.factModulePickersLabelLeft = "Compare facts collected on"; - $scope.factModulePickersLabelRight = "To facts collected on"; + $scope.factModulePickersLabelLeft = "Compare facts collected on or before"; + $scope.factModulePickersLabelRight = "To facts collected on or before"; $scope.modules = initialFactData.moduleOptions; @@ -40,6 +40,9 @@ function controller($rootScope, $scope.leftDate = initialFactData.leftSearchRange.from; $scope.rightDate = initialFactData.rightSearchRange.from; + $scope.leftScanDate = initialFactData.leftScanDate; + $scope.rightScanDate = initialFactData.rightScanDate; + function setHeaderValues(viewType) { if (viewType === 'singleHost') { $scope.comparisonLeftHeader = $scope.leftScanDate; @@ -58,7 +61,6 @@ function controller($rootScope, var leftRange = searchConfig.leftRange; var rightRange = searchConfig.rightRange; var activeModule = searchConfig.module; - var leftScanDate, rightScanDate; if (!factData) { @@ -68,12 +70,12 @@ function controller($rootScope, activeModule.name, leftRange, rightRange) - .thenAll(function(factDataAndModules) { + .then(function(factDataAndModules) { var responses = factDataAndModules[1]; var data = _.pluck(responses, 'fact'); - leftScanDate = moment(responses[0].timestamp); - rightScanDate = moment(responses[1].timestamp); + $scope.leftScanDate = moment(responses[0].timestamp); + $scope.rightScanDate = moment(responses[1].timestamp); return data; }, true); @@ -82,7 +84,8 @@ function controller($rootScope, waitIndicator('start'); return _(factData) - .thenAll(function(facts) { + .promise() + .then(function(facts) { // Make sure we always start comparison against // a non-empty array // @@ -132,7 +135,9 @@ function controller($rootScope, $scope.factData = info; - setHeaderValues(viewType, leftScanDate, rightScanDate); + setHeaderValues(viewType); + + return info; }).finally(function() { waitIndicator('stop'); diff --git a/awx/ui/static/js/system-tracking/system-tracking.partial.html b/awx/ui/static/js/system-tracking/system-tracking.partial.html index 64c770c3b5..c928f227dc 100644 --- a/awx/ui/static/js/system-tracking/system-tracking.partial.html +++ b/awx/ui/static/js/system-tracking/system-tracking.partial.html @@ -31,10 +31,10 @@

- There were no facts collected on the dates you selected ({{error.dateValues.leftDate|amDateFormat:'L'}} and {{error.dateValues.rightDate|amDateFormat:'L'}}). Please pick a different range or module and try again. + There were no facts collected on or before the dates you selected ({{error.dateValues.leftDate|amDateFormat:'L'}} and {{error.dateValues.rightDate|amDateFormat:'L'}}). Please pick a different range or module and try again.

- There were no facts collected on one of the dates you selected ({{error.dateValue|amDateFormat:'L'}}). Please select a different date and try again. + There were no facts collected on or before one of the dates you selected ({{error.dateValue|amDateFormat:'L'}}). Please select a different date and try again.

To setup or run scan jobs, edit the "{{inventory.name}}" inventory and select "Scan Jobs Templates". diff --git a/awx/ui/static/js/system-tracking/system-tracking.route.js b/awx/ui/static/js/system-tracking/system-tracking.route.js index 3b7ee26f11..edd8a3e9e0 100644 --- a/awx/ui/static/js/system-tracking/system-tracking.route.js +++ b/awx/ui/static/js/system-tracking/system-tracking.route.js @@ -32,22 +32,22 @@ export default { var data = getDataForComparison(hostIds, moduleParam, leftDate, rightDate). - thenAll(function(factDataAndModules) { - var moduleOptions = factDataAndModules[0]; - var factResponses = factDataAndModules[1]; - var factData = _.pluck(factResponses, 'fact'); + then(function(factDataAndModules) { + var moduleOptions = factDataAndModules[0]; + var factResponses = factDataAndModules[1]; + var factData = _.pluck(factResponses, 'fact'); - factData.leftSearchRange = leftDate; - factData.rightSearchRange = rightDate; + factData.leftSearchRange = leftDate; + factData.rightSearchRange = rightDate; - factData.leftScanDate = moment(factResponses[0].timestamp); - factData.rightScanDate = moment(factResponses[0].timestamp); + factData.leftScanDate = moment(factResponses[0].timestamp); + factData.rightScanDate = moment(factResponses[1].timestamp); - factData.moduleName = moduleParam; - factData.moduleOptions = moduleOptions; + factData.moduleName = moduleParam; + factData.moduleOptions = moduleOptions; - return factData; - }, true) + return factData; + }, true) .value(); return data;