CLOUDSTACK-10104: Optimize database transactions in ListDomain API to improve performance (#2282)

While creating the response object for the 'listDomain' API, several database calls are triggered to fetch details like parent domain, project limit, IP limit, etc. These database calls are triggered for each record found in the main fetch query, which is causing the response to slow down.

Fix:
The database transactions are reduced to improve response of the Listdomain API
This commit is contained in:
PranaliM 2018-01-05 21:51:46 +05:30 committed by Rohit Yadav
parent bf4f1bbb90
commit 5fad84174a
9 changed files with 341 additions and 24 deletions

View File

@ -104,6 +104,14 @@ public interface ResourceLimitService {
*/
public long findCorrectResourceLimitForDomain(Domain domain, ResourceType type);
/**
* Finds the default resource limit for a specified type.
*
* @param resourceType
* @return resource limit
*/
public long findDefaultResourceLimitForDomain(ResourceType resourceType);
/**
* Increments the resource count
*

View File

@ -867,6 +867,15 @@ public class ApiDBUtils {
return s_resourceLimitMgr.findCorrectResourceLimitForAccount(accountId, limit, type);
}
public static long findCorrectResourceLimitForDomain(Long limit, ResourceType resourceType, long domainId) {
//-- No limits for Root domain
if (domainId == Domain.ROOT_DOMAIN) {
return Resource.RESOURCE_UNLIMITED;
}
//--If limit doesn't have a value then fetch default limit from the configs
return (limit == null) ? s_resourceLimitMgr.findDefaultResourceLimitForDomain(resourceType) : limit;
}
public static long getResourceCount(ResourceType type, long accountId) {
AccountVO account = s_accountDao.findById(accountId);
@ -981,6 +990,10 @@ public class ApiDBUtils {
return s_domainDao.findByIdIncludingRemoved(domainId);
}
public static DomainJoinVO findDomainJoinVOById(Long domainId) {
return s_domainJoinDao.findByIdIncludingRemoved(domainId);
}
public static DomainVO findDomainByIdIncludingRemoved(Long domainId) {
return s_domainDao.findByIdIncludingRemoved(domainId);
}

View File

@ -1890,8 +1890,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
respView = ResponseView.Full;
}
List<DomainResponse> domainResponses = ViewResponseHelper.createDomainResponse(respView, cmd.getDetails(), result.first().toArray(
new DomainJoinVO[result.first().size()]));
List<DomainResponse> domainResponses = ViewResponseHelper.createDomainResponse(respView, cmd.getDetails(), result.first());
response.setResponses(domainResponses, result.second());
return response;
}
@ -1901,9 +1900,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Long domainId = cmd.getId();
boolean listAll = cmd.listAll();
boolean isRecursive = false;
Domain domain = null;
if (domainId != null) {
Domain domain = _domainDao.findById(domainId);
domain = _domainDao.findById(domainId);
if (domain == null) {
throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
}
@ -1947,7 +1947,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
if (domainId != null) {
if (isRecursive) {
sc.setParameters("path", _domainDao.findById(domainId).getPath() + "%");
if(domain == null){
domain = _domainDao.findById(domainId);
}
sc.setParameters("path", domain.getPath() + "%");
} else {
sc.setParameters("id", domainId);
}

View File

@ -18,11 +18,16 @@ package com.cloud.api.query;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.cloud.configuration.Resource;
import com.cloud.domain.Domain;
import org.apache.log4j.Logger;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
@ -375,14 +380,164 @@ public class ViewResponseHelper {
return new ArrayList<StoragePoolResponse>(vrDataList.values());
}
public static List<DomainResponse> createDomainResponse(ResponseView view, EnumSet<DomainDetails> details, DomainJoinVO... domains) {
public static List<DomainResponse> createDomainResponse(ResponseView view, EnumSet<DomainDetails> details, List<DomainJoinVO> domains) {
List<DomainResponse> respList = new ArrayList<DomainResponse>();
for (DomainJoinVO vt : domains){
respList.add(ApiDBUtils.newDomainResponse(view, details, vt));
//-- Coping the list to keep original order
List<DomainJoinVO> domainsCopy = new ArrayList<>(domains);
Collections.sort(domainsCopy, DomainJoinVO.domainIdComparator);
for (DomainJoinVO domainJoinVO : domains){
//-- Set parent information
DomainJoinVO parentDomainJoinVO = searchParentDomainUsingBinary(domainsCopy, domainJoinVO);
if(parentDomainJoinVO == null && domainJoinVO.getParent() != null) {
//-- fetch the parent from the database
parentDomainJoinVO = ApiDBUtils.findDomainJoinVOById(domainJoinVO.getParent());
if(parentDomainJoinVO != null) {
//-- Add parent domain to the domain copy for future use
domainsCopy.add(parentDomainJoinVO);
Collections.sort(domainsCopy, DomainJoinVO.domainIdComparator);
}
}
if(parentDomainJoinVO != null) {
domainJoinVO.setParentName(parentDomainJoinVO.getName());
domainJoinVO.setParentUuid(parentDomainJoinVO.getUuid());
}
//-- Set correct resource limits
if(domainJoinVO.getParent() != null && domainJoinVO.getParent() != Domain.ROOT_DOMAIN) {
Map<Resource.ResourceType, Long> resourceLimitMap = new HashMap<>();
copyResourceLimitsIntoMap(resourceLimitMap, domainJoinVO);
//-- Fetching the parent domain resource limit if absent in current domain
setParentResourceLimitIfNeeded(resourceLimitMap, domainJoinVO, domainsCopy);
//-- copy the final correct resource limit
copyResourceLimitsFromMap(resourceLimitMap, domainJoinVO);
}
respList.add(ApiDBUtils.newDomainResponse(view, details, domainJoinVO));
}
return respList;
}
private static DomainJoinVO searchParentDomainUsingBinary(List<DomainJoinVO> domainsCopy, DomainJoinVO domainJoinVO){
Long parentId = domainJoinVO.getParent() == null ? 0 : domainJoinVO.getParent();
int totalDomains = domainsCopy.size();
int left = 0;
int right = totalDomains -1;
while(left <= right){
int middle = (left + right) /2;
DomainJoinVO middleObject = domainsCopy.get(middle);
if(middleObject.getId() == parentId){
return middleObject;
}
if(middleObject.getId() > parentId){
right = middle - 1 ;
}
else{
left = middle + 1;
}
}
return null;
}
private static void copyResourceLimitsIntoMap(Map<Resource.ResourceType, Long> resourceLimitMap, DomainJoinVO domainJoinVO){
resourceLimitMap.put(Resource.ResourceType.user_vm, domainJoinVO.getVmLimit());
resourceLimitMap.put(Resource.ResourceType.public_ip, domainJoinVO.getIpLimit());
resourceLimitMap.put(Resource.ResourceType.volume, domainJoinVO.getVolumeLimit());
resourceLimitMap.put(Resource.ResourceType.snapshot, domainJoinVO.getSnapshotLimit());
resourceLimitMap.put(Resource.ResourceType.template, domainJoinVO.getTemplateLimit());
resourceLimitMap.put(Resource.ResourceType.network, domainJoinVO.getNetworkLimit());
resourceLimitMap.put(Resource.ResourceType.vpc, domainJoinVO.getVpcLimit());
resourceLimitMap.put(Resource.ResourceType.cpu, domainJoinVO.getCpuLimit());
resourceLimitMap.put(Resource.ResourceType.memory, domainJoinVO.getMemoryLimit());
resourceLimitMap.put(Resource.ResourceType.primary_storage, domainJoinVO.getPrimaryStorageLimit());
resourceLimitMap.put(Resource.ResourceType.secondary_storage, domainJoinVO.getSecondaryStorageLimit());
resourceLimitMap.put(Resource.ResourceType.project, domainJoinVO.getProjectLimit());
}
private static void copyResourceLimitsFromMap(Map<Resource.ResourceType, Long> resourceLimitMap, DomainJoinVO domainJoinVO){
domainJoinVO.setVmLimit(resourceLimitMap.get(Resource.ResourceType.user_vm));
domainJoinVO.setIpLimit(resourceLimitMap.get(Resource.ResourceType.public_ip));
domainJoinVO.setVolumeLimit(resourceLimitMap.get(Resource.ResourceType.volume));
domainJoinVO.setSnapshotLimit(resourceLimitMap.get(Resource.ResourceType.snapshot));
domainJoinVO.setTemplateLimit(resourceLimitMap.get(Resource.ResourceType.template));
domainJoinVO.setNetworkLimit(resourceLimitMap.get(Resource.ResourceType.network));
domainJoinVO.setVpcLimit(resourceLimitMap.get(Resource.ResourceType.vpc));
domainJoinVO.setCpuLimit(resourceLimitMap.get(Resource.ResourceType.cpu));
domainJoinVO.setMemoryLimit(resourceLimitMap.get(Resource.ResourceType.memory));
domainJoinVO.setPrimaryStorageLimit(resourceLimitMap.get(Resource.ResourceType.primary_storage));
domainJoinVO.setSecondaryStorageLimit(resourceLimitMap.get(Resource.ResourceType.secondary_storage));
domainJoinVO.setProjectLimit(resourceLimitMap.get(Resource.ResourceType.project));
}
private static void setParentResourceLimitIfNeeded(Map<Resource.ResourceType, Long> resourceLimitMap, DomainJoinVO domainJoinVO, List<DomainJoinVO> domainsCopy) {
DomainJoinVO parentDomainJoinVO = searchParentDomainUsingBinary(domainsCopy, domainJoinVO);
if(parentDomainJoinVO != null) {
Long vmLimit = resourceLimitMap.get(Resource.ResourceType.user_vm);
Long ipLimit = resourceLimitMap.get(Resource.ResourceType.public_ip);
Long volumeLimit = resourceLimitMap.get(Resource.ResourceType.volume);
Long snapshotLimit = resourceLimitMap.get(Resource.ResourceType.snapshot);
Long templateLimit = resourceLimitMap.get(Resource.ResourceType.template);
Long networkLimit = resourceLimitMap.get(Resource.ResourceType.network);
Long vpcLimit = resourceLimitMap.get(Resource.ResourceType.vpc);
Long cpuLimit = resourceLimitMap.get(Resource.ResourceType.cpu);
Long memoryLimit = resourceLimitMap.get(Resource.ResourceType.memory);
Long primaryStorageLimit = resourceLimitMap.get(Resource.ResourceType.primary_storage);
Long secondaryStorageLimit = resourceLimitMap.get(Resource.ResourceType.secondary_storage);
Long projectLimit = resourceLimitMap.get(Resource.ResourceType.project);
if (vmLimit == null) {
vmLimit = parentDomainJoinVO.getVmLimit();
resourceLimitMap.put(Resource.ResourceType.user_vm, vmLimit);
}
if (ipLimit == null) {
ipLimit = parentDomainJoinVO.getIpLimit();
resourceLimitMap.put(Resource.ResourceType.public_ip, ipLimit);
}
if (volumeLimit == null) {
volumeLimit = parentDomainJoinVO.getVolumeLimit();
resourceLimitMap.put(Resource.ResourceType.volume, volumeLimit);
}
if (snapshotLimit == null) {
snapshotLimit = parentDomainJoinVO.getSnapshotLimit();
resourceLimitMap.put(Resource.ResourceType.snapshot, snapshotLimit);
}
if (templateLimit == null) {
templateLimit = parentDomainJoinVO.getTemplateLimit();
resourceLimitMap.put(Resource.ResourceType.template, templateLimit);
}
if (networkLimit == null) {
networkLimit = parentDomainJoinVO.getNetworkLimit();
resourceLimitMap.put(Resource.ResourceType.network, networkLimit);
}
if (vpcLimit == null) {
vpcLimit = parentDomainJoinVO.getVpcLimit();
resourceLimitMap.put(Resource.ResourceType.vpc, vpcLimit);
}
if (cpuLimit == null) {
cpuLimit = parentDomainJoinVO.getCpuLimit();
resourceLimitMap.put(Resource.ResourceType.cpu, cpuLimit);
}
if (memoryLimit == null) {
memoryLimit = parentDomainJoinVO.getMemoryLimit();
resourceLimitMap.put(Resource.ResourceType.memory, memoryLimit);
}
if (primaryStorageLimit == null) {
primaryStorageLimit = parentDomainJoinVO.getPrimaryStorageLimit();
resourceLimitMap.put(Resource.ResourceType.primary_storage, primaryStorageLimit);
}
if (secondaryStorageLimit == null) {
secondaryStorageLimit = parentDomainJoinVO.getSecondaryStorageLimit();
resourceLimitMap.put(Resource.ResourceType.secondary_storage, secondaryStorageLimit);
}
if (projectLimit == null) {
projectLimit = parentDomainJoinVO.getProjectLimit();
resourceLimitMap.put(Resource.ResourceType.project, projectLimit);
}
//-- try till parent present
if (parentDomainJoinVO.getParent() != null && parentDomainJoinVO.getParent() != Domain.ROOT_DOMAIN) {
setParentResourceLimitIfNeeded(resourceLimitMap, parentDomainJoinVO, domainsCopy);
}
}
}
public static List<AccountResponse> createAccountResponse(ResponseView view, AccountJoinVO... accounts) {
List<AccountResponse> respList = new ArrayList<AccountResponse>();
for (AccountJoinVO vt : accounts){

View File

@ -57,15 +57,14 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
domainResponse.setId(domain.getUuid());
domainResponse.setLevel(domain.getLevel());
domainResponse.setNetworkDomain(domain.getNetworkDomain());
Domain parentDomain = ApiDBUtils.findDomainById(domain.getParent());
if (parentDomain != null) {
domainResponse.setParentDomainId(parentDomain.getUuid());
if (domain.getParentUuid() != null) {
domainResponse.setParentDomainId(domain.getParentUuid());
}
StringBuilder domainPath = new StringBuilder("ROOT");
(domainPath.append(domain.getPath())).deleteCharAt(domainPath.length() - 1);
domainResponse.setPath(domainPath.toString());
if (domain.getParent() != null) {
domainResponse.setParentDomainName(ApiDBUtils.findDomainById(domain.getParent()).getName());
domainResponse.setParentDomainName(domain.getParentName());
}
if (domain.getChildCount() > 0) {
domainResponse.setHasChild(true);
@ -79,7 +78,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
setResourceLimits(domain, fullView, domainResponse);
//get resource limits for projects
long projectLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getProjectLimit(), fullView, ResourceType.project, domain.getId());
long projectLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getProjectLimit(), ResourceType.project, domain.getId());
String projectLimitDisplay = (fullView || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit);
long projectTotal = (domain.getProjectTotal() == null) ? 0 : domain.getProjectTotal();
String projectAvail = (fullView || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal);
@ -104,7 +103,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setVmTotal(vmTotal);
response.setVmAvailable(vmAvail);
long ipLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getIpLimit(), fullView, ResourceType.public_ip, domain.getId());
long ipLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getIpLimit(), ResourceType.public_ip, domain.getId());
String ipLimitDisplay = (fullView || ipLimit == -1) ? "Unlimited" : String.valueOf(ipLimit);
long ipTotal = (domain.getIpTotal() == null) ? 0 : domain.getIpTotal();
String ipAvail = ((fullView || ipLimit == -1)) ? "Unlimited" : String.valueOf(ipLimit - ipTotal);
@ -112,7 +111,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setIpTotal(ipTotal);
response.setIpAvailable(ipAvail);
long volumeLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getVolumeLimit(), fullView, ResourceType.volume, domain.getId());
long volumeLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getVolumeLimit(), ResourceType.volume, domain.getId());
String volumeLimitDisplay = (fullView || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit);
long volumeTotal = (domain.getVolumeTotal() == null) ? 0 : domain.getVolumeTotal();
String volumeAvail = (fullView || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit - volumeTotal);
@ -120,7 +119,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setVolumeTotal(volumeTotal);
response.setVolumeAvailable(volumeAvail);
long snapshotLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getSnapshotLimit(), fullView, ResourceType.snapshot, domain.getId());
long snapshotLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getSnapshotLimit(), ResourceType.snapshot, domain.getId());
String snapshotLimitDisplay = (fullView || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit);
long snapshotTotal = (domain.getSnapshotTotal() == null) ? 0 : domain.getSnapshotTotal();
String snapshotAvail = (fullView || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit - snapshotTotal);
@ -128,7 +127,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setSnapshotTotal(snapshotTotal);
response.setSnapshotAvailable(snapshotAvail);
Long templateLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getTemplateLimit(), fullView, ResourceType.template, domain.getId());
Long templateLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getTemplateLimit(), ResourceType.template, domain.getId());
String templateLimitDisplay = (fullView || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit);
Long templateTotal = (domain.getTemplateTotal() == null) ? 0 : domain.getTemplateTotal();
String templateAvail = (fullView || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit - templateTotal);
@ -137,7 +136,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setTemplateAvailable(templateAvail);
//get resource limits for networks
long networkLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getNetworkLimit(), fullView, ResourceType.network, domain.getId());
long networkLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getNetworkLimit(), ResourceType.network, domain.getId());
String networkLimitDisplay = (fullView || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit);
long networkTotal = (domain.getNetworkTotal() == null) ? 0 : domain.getNetworkTotal();
String networkAvail = (fullView || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit - networkTotal);
@ -146,7 +145,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setNetworkAvailable(networkAvail);
//get resource limits for vpcs
long vpcLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getVpcLimit(), fullView, ResourceType.vpc, domain.getId());
long vpcLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getVpcLimit(), ResourceType.vpc, domain.getId());
String vpcLimitDisplay = (fullView || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit);
long vpcTotal = (domain.getVpcTotal() == null) ? 0 : domain.getVpcTotal();
String vpcAvail = (fullView || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit - vpcTotal);
@ -155,7 +154,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setVpcAvailable(vpcAvail);
//get resource limits for cpu cores
long cpuLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getCpuLimit(), fullView, ResourceType.cpu, domain.getId());
long cpuLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getCpuLimit(), ResourceType.cpu, domain.getId());
String cpuLimitDisplay = (fullView || cpuLimit == -1) ? "Unlimited" : String.valueOf(cpuLimit);
long cpuTotal = (domain.getCpuTotal() == null) ? 0 : domain.getCpuTotal();
String cpuAvail = (fullView || cpuLimit == -1) ? "Unlimited" : String.valueOf(cpuLimit - cpuTotal);
@ -164,7 +163,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setCpuAvailable(cpuAvail);
//get resource limits for memory
long memoryLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getMemoryLimit(), fullView, ResourceType.memory, domain.getId());
long memoryLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getMemoryLimit(), ResourceType.memory, domain.getId());
String memoryLimitDisplay = (fullView || memoryLimit == -1) ? "Unlimited" : String.valueOf(memoryLimit);
long memoryTotal = (domain.getMemoryTotal() == null) ? 0 : domain.getMemoryTotal();
String memoryAvail = (fullView || memoryLimit == -1) ? "Unlimited" : String.valueOf(memoryLimit - memoryTotal);
@ -173,7 +172,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setMemoryAvailable(memoryAvail);
//get resource limits for primary storage space and convert it from Bytes to GiB
long primaryStorageLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getPrimaryStorageLimit(), fullView, ResourceType.primary_storage, domain.getId());
long primaryStorageLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getPrimaryStorageLimit(), ResourceType.primary_storage, domain.getId());
String primaryStorageLimitDisplay = (fullView || primaryStorageLimit == -1) ? "Unlimited" : String.valueOf(primaryStorageLimit / ResourceType.bytesToGiB);
long primaryStorageTotal = (domain.getPrimaryStorageTotal() == null) ? 0 : (domain.getPrimaryStorageTotal() / ResourceType.bytesToGiB);
String primaryStorageAvail = (fullView || primaryStorageLimit == -1) ? "Unlimited" : String.valueOf((primaryStorageLimit / ResourceType.bytesToGiB) - primaryStorageTotal);
@ -182,7 +181,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setPrimaryStorageAvailable(primaryStorageAvail);
//get resource limits for secondary storage space and convert it from Bytes to GiB
long secondaryStorageLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getSecondaryStorageLimit(), fullView, ResourceType.secondary_storage, domain.getId());
long secondaryStorageLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getSecondaryStorageLimit(), ResourceType.secondary_storage, domain.getId());
String secondaryStorageLimitDisplay = (fullView || secondaryStorageLimit == -1) ? "Unlimited" : String.valueOf(secondaryStorageLimit / ResourceType.bytesToGiB);
long secondaryStorageTotal = (domain.getSecondaryStorageTotal() == null) ? 0 : (domain.getSecondaryStorageTotal() / ResourceType.bytesToGiB);
String secondaryStorageAvail = (fullView || secondaryStorageLimit == -1) ? "Unlimited" : String.valueOf((secondaryStorageLimit / ResourceType.bytesToGiB) - secondaryStorageTotal);

View File

@ -16,11 +16,13 @@
// under the License.
package com.cloud.api.query.vo;
import java.util.Comparator;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
@ -149,6 +151,12 @@ public class DomainJoinVO extends BaseViewVO implements InternalIdentity, Identi
@Column(name="secondaryStorageTotal")
private Long secondaryStorageTotal;
@Transient
private String parentName;
@Transient
private String parentUuid;
public DomainJoinVO() {
}
@ -498,4 +506,33 @@ public class DomainJoinVO extends BaseViewVO implements InternalIdentity, Identi
this.secondaryStorageLimit = secondaryStorageLimit;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public String getParentUuid() {
return parentUuid;
}
public void setParentUuid(String parentUuid) {
this.parentUuid = parentUuid;
}
public static Comparator<DomainJoinVO> domainIdComparator
= new Comparator<DomainJoinVO>() {
public int compare(DomainJoinVO domainJoinVO1, DomainJoinVO domainJoinVO2) {
Long domainId1 = domainJoinVO1.getId();
Long domainId2 = domainJoinVO2.getId();
//-- ascending order
return domainId1.compareTo(domainId2);
}
};
}

View File

@ -410,6 +410,17 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
return max;
}
public long findDefaultResourceLimitForDomain(ResourceType resourceType) {
Long resourceLimit = null;
resourceLimit = domainResourceLimitMap.get(resourceType);
if (resourceLimit != null && (resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage)) {
resourceLimit = resourceLimit * ResourceType.bytesToGiB;
} else {
resourceLimit = Long.valueOf(Resource.RESOURCE_UNLIMITED);
}
return resourceLimit;
}
@Override
@DB
public void checkResourceLimit(final Account account, final ResourceType type, long... count) throws ResourceAllocationException {

View File

@ -86,6 +86,11 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
return 0;
}
@Override
public long findDefaultResourceLimitForDomain(ResourceType resourceType) {
return 0;
}
/* (non-Javadoc)
* @see com.cloud.user.ResourceLimitService#incrementResourceCount(long, com.cloud.configuration.Resource.ResourceType, java.lang.Long[])
*/

View File

@ -19,7 +19,8 @@
# Import Local Modules
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.utils import (random_gen,
cleanup_resources)
cleanup_resources,
validateList)
from marvin.cloudstackAPI import *
from marvin.lib.base import (Domain,
Account,
@ -42,11 +43,11 @@ from marvin.lib.common import (get_domain,
wait_for_cleanup)
from nose.plugins.attrib import attr
from marvin.cloudstackException import CloudstackAPIException
from marvin.codes import PASS
import time
from pyVmomi.VmomiSupport import GetVersionFromVersionUri
class Services:
"""Test Account Services
@ -1470,6 +1471,91 @@ class TestUserLogin(cloudstackTestCase):
)
return
@attr(tags=["simulator", "advanced",
"advancedns", "basic", "eip", "sg"])
def test_ApiListDomain(self):
"""Test case to check the correctness of List domain API, to make sure that no field is missed in the output.
"""
# Steps for test scenario
# 1. create a domain
# 2. Create a sub-domain with domain created in step 1 as parent.
# Validate the following
# 1. listDomains returns created domain and sub-domain
# 2. The list Domain response has all the expected 44 elements/fields in it.
listDomainResponseElements = ["id", "name", "level", "parentdomainid", "parentdomainname", "haschild", "path",
"state",
"vmlimit", "vmtotal", "vmavailable", "iplimit", "iptotal", "ipavailable",
"volumelimit",
"volumetotal", "volumeavailable", "snapshotlimit", "snapshottotal",
"snapshotavailable",
"templatelimit", "templatetotal", "templateavailable", "projectlimit",
"projecttotal", "projectavailable",
"networklimit", "networktotal", "networkavailable", "vpclimit", "vpctotal",
"vpcavailable",
"cpulimit", "cputotal", "cpuavailable", "memorylimit", "memorytotal",
"memoryavailable", "primarystoragelimit",
"primarystoragetotal", "primarystorageavailable", "secondarystoragelimit",
"secondarystoragetotal", "secondarystorageavailable"
]
self.debug("Creating a domain for testing list domain reponse")
domain = Domain.create(
self.apiclient,
self.services["domain"],
parentdomainid=self.domain.id
)
self.debug("Domain: %s is created successfully." % domain.name)
self.debug("Validating the created domain")
list_domain = Domain.list(self.api_client, id=domain.id)
domain_list_validation_result = validateList(list_domain)
self.assertEqual(domain_list_validation_result[0], PASS,
"Domain list validation failed due to %s" %
domain_list_validation_result[2])
subDomain = Domain.create(
self.apiclient,
self.services["domain"],
parentdomainid=domain.id
)
self.debug("Sub-Domain: %s is created successfully." % subDomain.name)
self.cleanup.append(subDomain)
self.cleanup.append(domain)
self.debug("Validating the created sub-domain")
list_sub_domain = Domain.list(self.api_client, id=subDomain.id)
subdomain_list_validation_result = validateList(list_sub_domain)
self.assertEqual(subdomain_list_validation_result[0], PASS,
"Sub-Domain list validation failed due to %s" %
subdomain_list_validation_result[2])
self.debug("Checking that the listDomain response has all the elements.")
domainOutputString = list_domain[0].__dict__
for element in listDomainResponseElements:
self.assertTrue((element.lower() in domainOutputString), element + " field is missing in list domain rsponse.")
self.debug("Verified that the listDomain response has all the elements.")
self.debug("Checking that the list sub-domain response has all the elements.")
subdomainOutputString = list_sub_domain[0].__dict__
for element in listDomainResponseElements:
self.assertTrue((element.lower() in subdomainOutputString), element + " field is missing in list domain rsponse.")
self.debug("Verified that the list sub-Domain response has all the elements.")
return
@attr(tags=["login", "accounts", "simulator", "advanced",
"advancedns", "basic", "eip", "sg"])
def test_LoginApiDomain(self):