From 0efafdbf724e75d9d3ae02ff5fa90515b3d429d4 Mon Sep 17 00:00:00 2001 From: Siva Bavanasi Date: Tue, 5 May 2015 13:12:20 +0530 Subject: [PATCH] Closes-bug: #1451667 - WEBUI-CONFIG : Project quotas page throws "Error: 413 Request Entity Too Large" when there are large number of resources Change-Id: I34e468d1edeab568f7537c9686388bdf58000d92 --- webroot/config/quotas/api/parseURL.xml | 2 +- webroot/config/quotas/api/quotasconfig.api.js | 166 ++++++++---------- webroot/config/quotas/ui/js/quotas_config.js | 14 +- 3 files changed, 83 insertions(+), 99 deletions(-) diff --git a/webroot/config/quotas/api/parseURL.xml b/webroot/config/quotas/api/parseURL.xml index ae8d4a8dc..89f4cb28e 100644 --- a/webroot/config/quotas/api/parseURL.xml +++ b/webroot/config/quotas/api/parseURL.xml @@ -31,7 +31,7 @@ quotasconfigapi.updateProjectQuotas - /api/tenants/config/quota-used/:name + /api/tenants/config/quota-used/:id get quotasconfig quotasconfigapi.getProjectQuotaUsedInfo diff --git a/webroot/config/quotas/api/quotasconfig.api.js b/webroot/config/quotas/api/quotasconfig.api.js index 96b60f67e..d58468712 100644 --- a/webroot/config/quotas/api/quotasconfig.api.js +++ b/webroot/config/quotas/api/quotasconfig.api.js @@ -26,7 +26,6 @@ var util = require('util'); var url = require('url'); var configApiServer = require(process.mainModule.exports["corePath"] + '/src/serverroot/common/configServer.api'); -var async = require('async'); /** * @parseProjectQuotas * private function @@ -36,7 +35,9 @@ function parseProjectQuotas(error, projData, appData, callback) { var quotaData = projData["project"]["quota"]; if(quotaData != undefined) { - callback(error, projData); + var resQuota = {}; + resQuota.quota = quotaData; + callback(error, resQuota); } else { callback(error, null); @@ -84,7 +85,8 @@ function readProjectQuotas (projectIdStr, appData, callback) } else { setProjectQuotas(projectIdStr, appData, data, callback); } - }); + } + ); } /** @@ -149,12 +151,14 @@ function updateProjectQuotas(request, response, appData) var updateData = request.body; var url = "/project/"; url += projectId ; - configApiServer.apiPut(url, updateData, appData, function(err, data){ + var putObj = {}; + putObj.project = {uuid : projectId, quota : updateData.quota}; + configApiServer.apiPut(url, putObj, appData, function(err, data){ if (err) { commonUtils.handleJSONResponse(err, response, null); return; } - projectQuotasAPIGet(projectId, response, appData); + commonUtils.handleJSONResponse(err, response, data); }); } @@ -181,7 +185,7 @@ function processAsyncReq(req, callback) { function getProjectQuotaUsedInfo(request, response, appData) { var usedResCnt = {}; - var projName = validateProjectName(request); + var projId = validateProjectId(request); var resources = [{key : 'floating-ips', value : 'floating_ip'}, {key : 'floating-ip-pools', value : 'floating_ip_pool'}, {key : 'network-ipams', value : 'network_ipam'}, @@ -200,113 +204,93 @@ function getProjectQuotaUsedInfo(request, response, appData) var callObj = []; for(var featureCnt = 0; featureCnt < resources.length; featureCnt ++) { var reqObj = {}; - reqObj.url = '/' + resources[featureCnt].key; + reqObj.url = '/' + resources[featureCnt].key + '?parent_id=' + projId + '&count=true'; reqObj.appData = appData; callObj.push(reqObj); } async.map(callObj, processAsyncReq, function(err, data){ - if (err) { + if (err || data == null) { commonUtils.handleJSONResponse(err, response, null); return; } - var callVNObj = []; - var callSGObj = []; - for(var dataCnt = 0; dataCnt < data.length ; dataCnt++) { - for(var resCnt = 0; resCnt < resources.length; resCnt++) { - var resource = resources[resCnt]; + var dataLength = data.length; + var resLength = resources.length; + for(var dataCnt = 0; dataCnt < dataLength ; dataCnt++) { + for(var i = 0; i < resLength; i++) { + var resource = resources[i]; if(resource.key in data[dataCnt]) { - var resData = data[dataCnt][resource.key]; - var resCntPerProj = 0; - if(resData && resData.length > 0) { - for(var resDataCnt = 0; resDataCnt < resData.length ; resDataCnt++) { - if(resData[resDataCnt].fq_name[1] === projName) { - resCntPerProj ++; - if(resource.key === 'virtual-networks') { - var vnReqObj = {}; - vnReqObj.url = '/virtual-network/' + resData[resDataCnt].uuid; - vnReqObj.appData = appData; - callVNObj.push(vnReqObj); - } - if(resource.key === 'security-groups') { - var sgReqObj = {}; - sgReqObj.url = '/security-group/' + resData[resDataCnt].uuid; - sgReqObj.appData = appData; - callSGObj.push(sgReqObj); - } - } - } - } - usedResCnt[resource.value] = resCntPerProj; + var resCnt = data[dataCnt][resource.key].count; + usedResCnt[resource.value] = resCnt; } } } - if(callVNObj.length <= 0) { - usedResCnt['subnet'] = 0; - if(callSGObj.length <= 0) { - usedResCnt['security_group_rule'] = 0; - commonUtils.handleJSONResponse(err, response, usedResCnt); - } else { - getSecurityGroupRule(callSGObj, usedResCnt, response, function(error, data) { - commonUtils.handleJSONResponse(error, response, usedResCnt); - }); - } - } else { - if(callSGObj.length <= 0) { - usedResCnt['security_group_rule'] = 0; - getSubNetsUsedInfo(callVNObj, usedResCnt, response, function(error, data) { - commonUtils.handleJSONResponse(error, response, usedResCnt); - }); - } else { - getSubNetsUsedInfo(callVNObj, usedResCnt, response, function(error, data) { - getSecurityGroupRule(callSGObj, usedResCnt, response, function(error, data) { - commonUtils.handleJSONResponse(error, response, usedResCnt); - }); - }); + getSubNetsUsedInfo(projId, usedResCnt, appData, function(err, usedInfoSubnetCnt) { + if(err) { + commonUtils.handleJSONResponse(err, response, null); + return; } - } + getSecurityGroupRule(projId, usedInfoSubnetCnt, appData, function(err, finalUsedInfo) { + if(err) { + commonUtils.handleJSONResponse(err, response, null); + return; + } + commonUtils.handleJSONResponse(err, response, finalUsedInfo); + }); + }); }); } -function getSubNetsUsedInfo(callVNObj, usedResCnt, response, callback) +function getSubNetsUsedInfo(projId, usedResCnt, appData, callback) { //prepare used info count for subnets - async.map(callVNObj, processAsyncReq, function(err, resData) { - if (err) { - commonUtils.handleJSONResponse(err, response, null); - return; - } - var resCntPerProj = 0; - for(var resDataCnt = 0; resDataCnt < resData.length ; resDataCnt++) { - var ipams = resData[resDataCnt]['virtual-network']['network_ipam_refs']; - if(ipams && ipams.length > 0) { - for(var ipamCnt = 0; ipamCnt < ipams.length; ipamCnt++) { - var attr = ipams[ipamCnt]['attr']; - var subnetsCnt = attr['ipam_subnets'] ? attr['ipam_subnets'].length : 0; - resCntPerProj = resCntPerProj + subnetsCnt; - } - } + var vnDetailsURL = '/virtual-networks?parent_id=' + projId + '&detail=true&fields=network_ipam_refs'; + configApiServer.apiGet(vnDetailsURL, appData, + function(err, resData) { + if (!err) { + var resCnt = 0; + resData = resData['virtual-networks']; + if(resData != null) { + var resLength = resData.length; + for(var resDataCnt = 0; resDataCnt < resLength; resDataCnt++) { + var ipams = resData[resDataCnt]['virtual-network']['network_ipam_refs']; + if(ipams) { + var ipamsLength = ipams.length; + for(var ipamCnt = 0; ipamCnt < ipamsLength; ipamCnt++) { + var attr = ipams[ipamCnt]['attr']; + var subnetsCnt = attr['ipam_subnets'] ? attr['ipam_subnets'].length : 0; + resCnt = resCnt + subnetsCnt; + } + } + } + } + usedResCnt['subnet'] = resCnt; + } + callback(err, usedResCnt); } - usedResCnt['subnet'] = resCntPerProj; - callback(); - }); + ); } -function getSecurityGroupRule(sgReqObj, usedResCnt, response, callback) +function getSecurityGroupRule(projId, usedResCnt, appData, callback) { - //prepare used info count for subnets - async.map(sgReqObj, processAsyncReq, function(err, resData) { - if (err) { - commonUtils.handleJSONResponse(err, response, null); - return; - } - var subGrpCnt = 0; - for(var resDataCnt = 0; resDataCnt < resData.length ; resDataCnt++) { - var sg = resData[resDataCnt]['security-group']['security_group_entries']; - subGrpCnt += sg['policy_rule'] ? sg['policy_rule'].length : 0; + //prepare used info count for security group rules + var sgDetailsURL = '/security-groups?parent_id=' + projId + '&detail=true&fields=security_group_entries'; + configApiServer.apiGet(sgDetailsURL, appData, + function(err, resData) { + if (!err) { + var subGrpCnt = 0; + resData = resData['security-groups']; + if(resData != null) { + var resLength = resData.length; + for(var resDataCnt = 0; resDataCnt < resLength; resDataCnt++) { + var sg = resData[resDataCnt]['security-group']['security_group_entries']; + subGrpCnt += sg['policy_rule'] ? sg['policy_rule'].length : 0; + } + } + usedResCnt['security_group_rule'] = subGrpCnt; + } + callback(err, usedResCnt); } - usedResCnt['security_group_rule'] = subGrpCnt; - callback(); - }); + ); } function validateProjectId (request) diff --git a/webroot/config/quotas/ui/js/quotas_config.js b/webroot/config/quotas/ui/js/quotas_config.js index b0b7223d9..cae1c12f6 100644 --- a/webroot/config/quotas/ui/js/quotas_config.js +++ b/webroot/config/quotas/ui/js/quotas_config.js @@ -259,7 +259,7 @@ } function validateQuotaData(result) { - if(result && result["project"]) { + if(result && result["quota"]) { updateData = result fetchQuotaUsedInfo() } else { @@ -269,7 +269,7 @@ function fetchQuotaUsedInfo() { var selectedProject = $("#ddProjectSwitcher").data("contrailDropdown").getSelectedData()[0]; - doAjaxCall("/api/tenants/config/quota-used/" + selectedProject.text, + doAjaxCall("/api/tenants/config/quota-used/" + selectedProject.value, "GET", null, "successHandlerForQuotaUsed", "failureHandlerForQuotaUsed", null, null); } @@ -287,7 +287,7 @@ } function populateQuotaEditPopup() { - var data = updateData["project"]["quota"]; + var data = updateData["quota"]; for(var quotaCnt = 0;quotaCnt < quotaList.length;quotaCnt++) { var quotaKey = quotaList[quotaCnt].key; var comboDS = [{ text : 'Unlimited', value : -1 }]; @@ -312,7 +312,7 @@ } function bindDatatoGrid(usedInfo) { - var data = updateData["project"]["quota"]; + var data = updateData["quota"]; if(data != null && data != undefined) { var dsQuota = []; for(var quotaCnt = 0;quotaCnt < quotaList.length;quotaCnt++) { @@ -362,7 +362,7 @@ $("#gridQuotas").data("contrailGrid")._dataView.setData([]); gridQuotas.showGridMessage('loading'); var selectedProject = $("#ddProjectSwitcher").data("contrailDropdown").getSelectedData()[0]; - var updateQuota = data["project"]["quota"]; + var updateQuota = data["quota"]; for(var quotaCnt = 0;quotaCnt < quotaList.length;quotaCnt++) { var quotaKey = quotaList[quotaCnt].key; var comboInstanceValue = $('#' + quotaKey).data('contrailCombobox').value(); @@ -379,11 +379,11 @@ } window.successHandlerForQuotasUpdate = function(result) { - validateQuotaData(result); + fetchDataForQuota(); } window.failureHandlerForQuotasUpdate = function(err) { - gridQuotas.showGridMessage('errorGettingData'); + fetchDataForQuota(); } function destroy() {