diff --git a/api-docs.yml b/api-docs.yml index e1f5db50..f81667a4 100644 --- a/api-docs.yml +++ b/api-docs.yml @@ -72,6 +72,7 @@ paths: items: $ref: '#/components/schemas/Service' description: successful response + post: tags: - services @@ -970,6 +971,21 @@ paths: application/json: schema: description: successful response + /report: + get: + tags: + - report + description: retrieves a report of total services, users, etc + responses: + 200: + description: report + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Report' + description: report components: securitySchemes: @@ -1113,6 +1129,25 @@ components: type: array items: type: string + Report: + title: Report + type: object + properties: + totalServices: + type: integer + activeServices: + type: integer + draftServices: + type: integer + archiveServices: + type: integer + users: + type: integer + systems: + type: integer + totalTransactions: + type: integer + tags: - name: services description: '' diff --git a/app.js b/app.js index a69f6ae3..99b5d5a7 100644 --- a/app.js +++ b/app.js @@ -23,6 +23,7 @@ const System = require('./models/common/System'); const MQService = require('./models/mq/MQService'); const constants = require('./lib/util/constants'); const fuseHelper = require('./lib/util/fuse'); +const reportingRouter = require('./routes/report'); global.__basedir = __dirname; // connect to database @@ -174,6 +175,7 @@ function init() { const recorderController = require('./controllers/recorderController'); app.use('/recording',recorder.recordingRouter); app.use('/api/recording',recorder.apiRouter); + app.use('/api/report/',reportingRouter.router); const mqController = require('./controllers/mqController'); mqController.registerAllMQServices(); diff --git a/controllers/reportingController.js b/controllers/reportingController.js new file mode 100644 index 00000000..45cba9c4 --- /dev/null +++ b/controllers/reportingController.js @@ -0,0 +1,236 @@ +const MQService = require('../models/mq/MQService'); +const Service = require('../models/http/Service'); +//const Recording = require('../models/http/Recording'); +const User = require('../models/common/User'); +const System = require('../models/common/System'); +const DraftService = require ('../models/common/DraftService'); +const Archive = require ('../models/common/Archive'); + + +function getAllServicesByGroups(){ + return new Promise( + function(resolve, reject){ + Service.aggregate( + { + $group:{ + _id:"$sut.name", + totalServices: + { + $sum:1 + } + } + },{ + $project: + { + sut:"$_id", + services:"$totalServices", + _id:false + } + } + + ).then(function(result){ + resolve(result); + }).catch(function(err){ + reject(err); + }); + } + ); +} + +function getTotalTransactionCount(){ + + return new Promise( + function(resolve, reject){ + Service.aggregate( + { + $group:{_id:null,totalTransactions: {$sum:"$txnCount"}} + } + ).then(function(result){ + resolve(result[0].totalTransactions); + }) + .catch(function(err){ + reject(err); + }); + + + + } + ); + + + + +} + + +/** + * Returns a promise that returns the # of total Services+MQServices. Does not include archive/drafts + * @return A promise that returns the # of total Services+MQServices + */ +function getCountOfAllServices(){ + return new Promise(function(resolve,reject){ + Service.count({},function(err,serviceCount){ + if(err) + reject(err); + else{ + MQService.count({},function(err,mqServiceCount){ + if(err) + reject(err); + else{ + resolve(mqServiceCount+serviceCount); + } + }); + } + }); + }); +} + +/** + * Returns a promise that returns the # of active Services+MQServices. Does not include archive/drafts + * @return A promise that returns the # of active Services+MQServices + */ +function getCountOfActiveServices(){ + return new Promise(function(resolve,reject){ + Service.count({running:true},function(err,serviceCount){ + if(err) + reject(err); + else{ + MQService.count({running:true},function(err,mqServiceCount){ + if(err) + reject(err); + else{ + resolve(mqServiceCount+serviceCount); + } + }); + } + }); + }); +} + + +/** + * Returns a promise that evaluates to the # of draft services + */ +function getCountOfDraftServices(){ + return new Promise(function(resolve,reject){ + DraftService.count({}, + function(err,count){ + if(err) + reject(err); + else + resolve(count); + + + } + ); + }); +} + +/** + * Returns a promise that evaluates to the # of archive services + */ +function getCountOfArchiveServices(){ + return new Promise(function(resolve,reject){ + Archive.count({}, + function(err,count){ + if(err) + reject(err); + else + resolve(count); + + + } + ); + }); +} + +/** + * Returns a promise that evaluates to the # of users + */ +function getCountOfUsers(){ + return new Promise(function(resolve,reject){ + User.count({}, + function(err,count){ + if(err) + reject(err); + else + resolve(count); + + + } + ); + }); +} + +/** + * Returns a promise that evaluates to the # of Systems + */ +function getCountOfSystems(){ + return new Promise(function(resolve,reject){ + System.count({}, + function(err,count){ + if(err) + reject(err); + else + resolve(count); + + + } + ); + }); +} + +/** + * Runs + returns a full report + * @param {*} req express req + * @param {*} rsp express rsp + * @param {*} next next middleware + */ +function fullReport(req,rsp,next){ + var report = {}; + var promises = []; + var promiseLabels = []; + + //Build list of promises + promises.push(getCountOfAllServices()); + promiseLabels.push("totalServices"); + + promises.push(getCountOfActiveServices()); + promiseLabels.push("activeServices"); + + promises.push(getCountOfDraftServices()); + promiseLabels.push("draftServices"); + + promises.push(getCountOfArchiveServices()); + promiseLabels.push("archiveServices"); + + promises.push(getCountOfUsers()); + promiseLabels.push("users"); + + promises.push(getCountOfSystems()); + promiseLabels.push("systems"); + + promises.push(getTotalTransactionCount()); + promiseLabels.push("totalTransactions"); + + promises.push(getAllServicesByGroups()); + promiseLabels.push("servicesByGroup"); + + Promise.all(promises).then( + function(vals){ + for(let i = 0; i < vals.length; i++){ + report[promiseLabels[i]] = vals[i]; + } + rsp.json(report); + } + , + function(err){ + handleError(err,rsp,500); + } + ); + +} + +module.exports = { + fullReport : fullReport +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index f39c6b39..d0a4c8eb 100644 --- a/public/index.html +++ b/public/index.html @@ -125,7 +125,8 @@
Operations:
diff --git a/public/js/app/controllers.js b/public/js/app/controllers.js index 3f5f48fa..59fc6a2e 100644 --- a/public/js/app/controllers.js +++ b/public/js/app/controllers.js @@ -27,9 +27,9 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f }; }]) - .controller("myMenuAppController", ['$scope', 'apiHistoryService', 'sutService', 'authService', 'suggestionsService', 'helperFactory', 'ctrlConstants','modalService', 'mqInfoFactory', + .controller("myMenuAppController", ['$scope', 'apiHistoryService', 'sutService', 'authService', 'suggestionsService', 'helperFactory', 'commonCodeFactory','ctrlConstants','modalService', 'mqInfoFactory', - function ($scope, apiHistoryService, sutService, authService, suggestionsService, helperFactory, ctrlConstants, modalService, mqInfoFactory) { + function ($scope, apiHistoryService, sutService, authService, suggestionsService, helperFactory, commonCodeFactory, ctrlConstants, modalService, mqInfoFactory) { $scope.canEdit = function(){ return true; } $scope.myUser = authService.getUserInfo().username; $scope.canChangeType = true; @@ -45,11 +45,12 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f id: 0 }], reqHeadersArr: [{ - id: 0, + id: 0, 'k': " " }], resHeadersArr: [{ - id: 0 - }] + id: 0, 'k': " " + }], + resStatus: " " }]; $scope.statusCodes = suggestionsService.getStatusCodes(); @@ -72,46 +73,11 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f }); $scope.publishservice = function (servicevo) { - - var i = servicevo.rawpairs.length; - while(i--){ - /* handle blank request payload - when you edit and make request payload empty - then request payload becomes empty string so duplicate request check wil not work. */ - if( servicevo.rawpairs[i].requestpayload == '' || servicevo.rawpairs[i].requestpayload === null){ - servicevo.rawpairs[i].requestpayload = undefined; - } - // handeling GET method without requestpayload - if(servicevo.rawpairs[i].method!== 'GET') - { - servicevo.rawpairs[i].getPayloadRequired = false; - } - - if(servicevo.rawpairs[i].method === 'GET'&& servicevo.rawpairs[i].getPayloadRequired === false){ - servicevo.rawpairs[i].requestpayload = undefined; - } - } - //handle blank query params in rrpairs - servicevo.rawpairs.forEach(function(rrpair){ - var i = rrpair.queriesArr.length; - while(i--){ - if( rrpair.queriesArr[i].k == '' ){ - rrpair.queriesArr[i]={id: rrpair.queriesArr[i].id}; - } - } - }); - //handle blank Request Headers in rrpairs - servicevo.rawpairs.forEach(function(rrpair){ - var i = rrpair.reqHeadersArr.length; - while(i--){ - if(!rrpair.reqHeadersArr[i].k || rrpair.reqHeadersArr[i].k == ''){ - rrpair.reqHeadersArr[i]={id: rrpair.reqHeadersArr[i].id}; - } - } - }); try { + servicevo = commonCodeFactory.modifyServicevoBeforePublish(servicevo); if (helperFactory.isDuplicateReq(servicevo)) { $('#genricMsg-dialog').find('.modal-title').text(ctrlConstants.DUP_REQ_ERR_TITLE); - $('#genricMsg-dialog').find('.modal-body').text(ctrlConstants.DUP_REQ_ERR_BODY); + $('#genricMsg-dialog').find('.modal-body').html(ctrlConstants.DUP_REQ_ERR_BODY); $('#genricMsg-dialog').find('.modal-footer').html(ctrlConstants.DUPLICATE_CONFIRM_FOOTER); $('#genricMsg-dialog').modal('toggle'); } else { @@ -186,14 +152,12 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f }]) - .controller("viewRecorderController", ['$scope', '$http', '$routeParams', 'apiHistoryService', 'feedbackService', 'suggestionsService', 'helperFactory', 'ctrlConstants', '$timeout', 'authService', - function ($scope, $http, $routeParams, apiHistoryService, feedbackService, suggestionsService, helperFactory, ctrlConstants, $timeout, authService) { + .controller("viewRecorderController", ['$scope', '$http', '$routeParams', 'apiHistoryService', 'feedbackService', 'suggestionsService', 'helperFactory', 'commonCodeFactory','ctrlConstants', '$timeout', 'authService', + function ($scope, $http, $routeParams, apiHistoryService, feedbackService, suggestionsService, helperFactory, commonCodeFactory,ctrlConstants, $timeout, authService) { $scope.statusCodes = suggestionsService.getStatusCodes(); $scope.possibleHeaders = suggestionsService.getPossibleHeaders(); var totalRRPairs = 0; - - function processRRPairs(rrpairs) { var rrpairsRaw = []; var rrid = 0; @@ -360,10 +324,15 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f return true; } else { - return false; } }; + if(!newsutlist.includes($scope.servicevo.sut.name)){ + $('#genricMsg-dialog').find('.modal-title').html(ctrlConstants.EDIT_RECORDING_INFO_TITLE); + $('#genricMsg-dialog').find('.modal-body').html("You can\'t edit this recording because you aren\'t part of the group "+$scope.servicevo.sut.name+"."); + $('#genricMsg-dialog').find('.modal-footer').html(ctrlConstants.EDIT_SERV_INFO_FOOTER); + $('#genricMsg-dialog').modal('toggle'); + } }) .catch(function (err) { @@ -372,9 +341,10 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f $scope.publishService = function (servicevo) { try { + servicevo = commonCodeFactory.modifyServicevoBeforePublish(servicevo); if (helperFactory.isDuplicateReq(servicevo)) { $('#genricMsg-dialog').find('.modal-title').text(ctrlConstants.DUP_REQ_ERR_TITLE); - $('#genricMsg-dialog').find('.modal-body').text(ctrlConstants.DUP_REQ_ERR_BODY); + $('#genricMsg-dialog').find('.modal-body').html(ctrlConstants.DUP_REQ_ERR_BODY); $('#genricMsg-dialog').find('.modal-footer').html(ctrlConstants.DUPLICATE_CONFIRM_FOOTER); $('#genricMsg-dialog').modal('toggle'); } else { @@ -560,8 +530,8 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f this.getService(); }]) - .controller("showDraftController", ['$scope', '$q', '$http', '$routeParams', 'apiHistoryService', 'feedbackService', 'suggestionsService', 'helperFactory', 'ctrlConstants', 'sutService', 'authService', 'modalService', - function ($scope, $q, $http, $routeParams, apiHistoryService, feedbackService, suggestionsService, helperFactory, ctrlConstants, sutService, authService, modalService) { + .controller("showDraftController", ['$scope', '$q', '$http', '$routeParams', 'apiHistoryService', 'feedbackService', 'suggestionsService', 'helperFactory', 'commonCodeFactory','ctrlConstants', 'sutService', 'authService', 'modalService', + function ($scope, $q, $http, $routeParams, apiHistoryService, feedbackService, suggestionsService, helperFactory, commonCodeFactory, ctrlConstants, sutService, authService, modalService) { $scope.showDates = true; $scope.statusCodes = suggestionsService.getStatusCodes(); $scope.possibleHeaders = suggestionsService.getPossibleHeaders(); @@ -785,46 +755,11 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f $scope.updateService = function (servicevo) { - /* handle blank request payload - when you edit and make request payload empty - then request payload becomes empty string so duplicate request check wil not worker. */ - var i = servicevo.rawpairs.length; - while(i--){ - if( servicevo.rawpairs[i].requestpayload == '' || servicevo.rawpairs[i].requestpayload === null){ - servicevo.rawpairs[i].requestpayload = undefined; - } - // handeling GET method without requestpayload - if(servicevo.rawpairs[i].method!== 'GET') - { - servicevo.rawpairs[i].getPayloadRequired = false; - } - - if(servicevo.rawpairs[i].method === 'GET'&& servicevo.rawpairs[i].getPayloadRequired === false){ - servicevo.rawpairs[i].requestpayload = undefined; - } - } - - //handle blank query params in rrpairs. if you provide query param and then make it blank. - servicevo.rawpairs.forEach(function(rrpair){ - var i = rrpair.queriesArr.length; - while(i--){ - if( rrpair.queriesArr[i].k == '' ){ - rrpair.queriesArr[i]={id: rrpair.queriesArr[i].id}; - } - } - }); - //handle blank Request Headers in rrpairs - servicevo.rawpairs.forEach(function(rrpair){ - var i = rrpair.reqHeadersArr.length; - while(i--){ - if(!rrpair.reqHeadersArr[i].k || rrpair.reqHeadersArr[i].k == ''){ - rrpair.reqHeadersArr[i]={id: rrpair.reqHeadersArr[i].id}; - } - } - }); try { + servicevo = commonCodeFactory.modifyServicevoBeforePublish(servicevo); if (helperFactory.isDuplicateReq(servicevo)) { $('#genricMsg-dialog').find('.modal-title').text(ctrlConstants.DUP_REQ_ERR_TITLE); - $('#genricMsg-dialog').find('.modal-body').text(ctrlConstants.DUP_REQ_ERR_BODY); + $('#genricMsg-dialog').find('.modal-body').html(ctrlConstants.DUP_REQ_ERR_BODY); $('#genricMsg-dialog').find('.modal-footer').html(ctrlConstants.DUPLICATE_CONFIRM_FOOTER); $('#genricMsg-dialog').modal('toggle'); } else { @@ -974,6 +909,12 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f return false; } }; + if(!newsutlist.includes($scope.servicevo.sut.name)){ + $('#genricMsg-dialog').find('.modal-title').html(ctrlConstants.EDIT_RECORDING_INFO_TITLE); + $('#genricMsg-dialog').find('.modal-body').html("You can\'t edit this recording because you aren\'t part of the group "+$scope.servicevo.sut.name+"."); + $('#genricMsg-dialog').find('.modal-footer').html(ctrlConstants.EDIT_SERV_INFO_FOOTER); + $('#genricMsg-dialog').modal('toggle'); + } }) .catch(function (err) { @@ -1156,8 +1097,8 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f }); $scope.pollForRRPairs(); }]) - .controller("updateController", ['$scope', '$q', '$http', '$routeParams', 'apiHistoryService', 'feedbackService', 'suggestionsService', 'helperFactory', 'ctrlConstants', 'sutService', 'authService', "$location",'modalService', 'mqInfoFactory', - function ($scope, $q, $http, $routeParams, apiHistoryService, feedbackService, suggestionsService, helperFactory, ctrlConstants, sutService, authService, $location, modalService, mqInfoFactory) { + .controller("updateController", ['$scope', '$q', '$http', '$routeParams', 'apiHistoryService', 'feedbackService', 'suggestionsService', 'helperFactory', 'commonCodeFactory', 'ctrlConstants', 'sutService', 'authService', "$location",'modalService', 'mqInfoFactory', + function ($scope, $q, $http, $routeParams, apiHistoryService, feedbackService, suggestionsService, helperFactory, commonCodeFactory, ctrlConstants, sutService, authService, $location, modalService, mqInfoFactory) { $scope.showDates = true; $scope.statusCodes = suggestionsService.getStatusCodes(); $scope.possibleHeaders = suggestionsService.getPossibleHeaders(); @@ -1257,10 +1198,15 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f return true; } else { - return false; } }; + if(!newsutlist.includes($scope.servicevo.sut.name)){ + $('#genricMsg-dialog').find('.modal-title').html(ctrlConstants.EDIT_SERV_INFO_TITLE); + $('#genricMsg-dialog').find('.modal-body').html("You can\'t edit this service because you aren\'t part of the group "+$scope.servicevo.sut.name+". You can request access from user "+$scope.servicevo.lastUpdateUser+"."); + $('#genricMsg-dialog').find('.modal-footer').html(ctrlConstants.EDIT_SERV_INFO_FOOTER); + $('#genricMsg-dialog').modal('toggle'); + } }) .catch(function (err) { @@ -1381,64 +1327,16 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f }; this.getService(); - - - - $scope.viewRecorded = function () { $location.path("/update/" + $scope.servicevo.id + "/recorded") } - - $scope.updateService = function (servicevo) { - //handle blank query params in rrpairs - servicevo.rawpairs.forEach(function(rrpair){ - var i = rrpair.queriesArr.length; - while(i--){ - if( rrpair.queriesArr[i].k == '' ){ - rrpair.queriesArr[i]={id: rrpair.queriesArr[i].id}; - } - } - }); - /* handle blank request payload - when you edit and make request payload empty - then request payload becomes empty string so duplicate request check wil not work. */ - var i = servicevo.rawpairs.length; - while(i--){ - if( servicevo.rawpairs[i].requestpayload == '' || servicevo.rawpairs[i].requestpayload === null){ - servicevo.rawpairs[i].requestpayload = undefined; - } - // handeling GET method without requestpayload - if(servicevo.rawpairs[i].method!== 'GET') - { - servicevo.rawpairs[i].getPayloadRequired = false; - } - - if(servicevo.rawpairs[i].method === 'GET'&& servicevo.rawpairs[i].getPayloadRequired === false){ - servicevo.rawpairs[i].requestpayload = undefined; - } - } - - if($scope.servicevo.delayMax === null){ - $scope.servicevo.delayMax = 0; - } - if($scope.servicevo.delay === null){ - $scope.servicevo.delay = 0; - } - - //handle blank Request Headers in rrpairs - servicevo.rawpairs.forEach(function(rrpair){ - var i = rrpair.reqHeadersArr.length; - while(i--){ - if(!rrpair.reqHeadersArr[i].k || rrpair.reqHeadersArr[i].k == ''){ - rrpair.reqHeadersArr[i]={id: rrpair.reqHeadersArr[i].id}; - } - } - }); try { + servicevo = commonCodeFactory.modifyServicevoBeforePublish(servicevo); if (helperFactory.isDuplicateReq(servicevo)) { $('#genricMsg-dialog').find('.modal-title').text(ctrlConstants.DUP_REQ_ERR_TITLE); - $('#genricMsg-dialog').find('.modal-body').text(ctrlConstants.DUP_REQ_ERR_BODY); + $('#genricMsg-dialog').find('.modal-body').html(ctrlConstants.DUP_REQ_ERR_BODY); $('#genricMsg-dialog').find('.modal-footer').html(ctrlConstants.DUPLICATE_CONFIRM_FOOTER); $('#genricMsg-dialog').modal('toggle'); } else { @@ -1453,8 +1351,6 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f } }; - - $scope.serviceInfo = function () { console.log($routeParams.id); $http.get('/api/services/' + $routeParams.id) @@ -2642,7 +2538,7 @@ var ctrl = angular.module("mockapp.controllers", ['mockapp.services', 'mockapp.f //Put all the hard coding or constants here for controller. ctrl.constant("ctrlConstants", { "DUP_REQ_ERR_TITLE": "Duplicate Request Error", - "DUP_REQ_ERR_BODY": "Two Requests are same. Either change request data or relative path of duplicate requests.", + "DUP_REQ_ERR_BODY": "Two Requests are same. These RR Pairs are highlighted with below red colour heading.