diff --git a/api/src/com/cloud/user/ResourceLimitService.java b/api/src/com/cloud/user/ResourceLimitService.java index 901fa06ad98..52e03568984 100644 --- a/api/src/com/cloud/user/ResourceLimitService.java +++ b/api/src/com/cloud/user/ResourceLimitService.java @@ -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 * diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 9f67aa748f5..22ed2437d4d 100644 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -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); } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index efe31cbd895..42034557d73 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -1890,8 +1890,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q respView = ResponseView.Full; } - List domainResponses = ViewResponseHelper.createDomainResponse(respView, cmd.getDetails(), result.first().toArray( - new DomainJoinVO[result.first().size()])); + List 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); } diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 11af5a9e760..940ae288c42 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -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(vrDataList.values()); } - public static List createDomainResponse(ResponseView view, EnumSet details, DomainJoinVO... domains) { + public static List createDomainResponse(ResponseView view, EnumSet details, List domains) { List respList = new ArrayList(); - for (DomainJoinVO vt : domains){ - respList.add(ApiDBUtils.newDomainResponse(view, details, vt)); + //-- Coping the list to keep original order + List 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 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 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 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 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 resourceLimitMap, DomainJoinVO domainJoinVO, List 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 createAccountResponse(ResponseView view, AccountJoinVO... accounts) { List respList = new ArrayList(); for (AccountJoinVO vt : accounts){ diff --git a/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java index 1f123cdab17..497fc2c13a3 100644 --- a/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java @@ -57,15 +57,14 @@ public class DomainJoinDaoImpl extends GenericDaoBase 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 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 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 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 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 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 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 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 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 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 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 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); diff --git a/server/src/com/cloud/api/query/vo/DomainJoinVO.java b/server/src/com/cloud/api/query/vo/DomainJoinVO.java index a7c45609f28..6f4d6b7bb88 100644 --- a/server/src/com/cloud/api/query/vo/DomainJoinVO.java +++ b/server/src/com/cloud/api/query/vo/DomainJoinVO.java @@ -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 domainIdComparator + = new Comparator() { + + public int compare(DomainJoinVO domainJoinVO1, DomainJoinVO domainJoinVO2) { + + Long domainId1 = domainJoinVO1.getId(); + Long domainId2 = domainJoinVO2.getId(); + + //-- ascending order + return domainId1.compareTo(domainId2); + } + + }; } diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 908483ab4aa..a1879297dd4 100644 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -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 { diff --git a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java b/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java index 0be5b1bc6e8..8ad08eef653 100644 --- a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java +++ b/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java @@ -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[]) */ diff --git a/test/integration/smoke/test_accounts.py b/test/integration/smoke/test_accounts.py index dffb00aaef4..08fa8134976 100644 --- a/test/integration/smoke/test_accounts.py +++ b/test/integration/smoke/test_accounts.py @@ -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):