Skip to content

Commit

Permalink
Merge "Closes-bug: #1451667 - WEBUI-CONFIG : Project quotas page thro…
Browse files Browse the repository at this point in the history
…ws "Error: 413 Request Entity Too Large" when there are large number of resources" into R2.20
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed May 5, 2015
2 parents f7de566 + 0efafdb commit bfe0a3c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 99 deletions.
2 changes: 1 addition & 1 deletion webroot/config/quotas/api/parseURL.xml
Expand Up @@ -31,7 +31,7 @@
<callback>quotasconfigapi.updateProjectQuotas</callback>
</item>
<item>
<url>/api/tenants/config/quota-used/:name</url>
<url>/api/tenants/config/quota-used/:id</url>
<method>get</method>
<feature>quotasconfig</feature>
<callback>quotasconfigapi.getProjectQuotaUsedInfo</callback>
Expand Down
166 changes: 75 additions & 91 deletions webroot/config/quotas/api/quotasconfig.api.js
Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -84,7 +85,8 @@ function readProjectQuotas (projectIdStr, appData, callback)
} else {
setProjectQuotas(projectIdStr, appData, data, callback);
}
});
}
);
}

/**
Expand Down Expand Up @@ -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);
});
}

Expand All @@ -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'},
Expand All @@ -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)
Expand Down
14 changes: 7 additions & 7 deletions webroot/config/quotas/ui/js/quotas_config.js
Expand Up @@ -259,7 +259,7 @@
}

function validateQuotaData(result) {
if(result && result["project"]) {
if(result && result["quota"]) {
updateData = result
fetchQuotaUsedInfo()
} else {
Expand All @@ -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);
}

Expand All @@ -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 }];
Expand All @@ -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++) {
Expand Down Expand Up @@ -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();
Expand All @@ -379,11 +379,11 @@
}

window.successHandlerForQuotasUpdate = function(result) {
validateQuotaData(result);
fetchDataForQuota();
}

window.failureHandlerForQuotasUpdate = function(err) {
gridQuotas.showGridMessage('errorGettingData');
fetchDataForQuota();
}

function destroy() {
Expand Down

0 comments on commit bfe0a3c

Please sign in to comment.