cloudstack-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CLOUDSTACK-10104) Optimize database transactions in ListDomain API to improve performance
Date Fri, 05 Jan 2018 16:22:00 GMT

    [ https://issues.apache.org/jira/browse/CLOUDSTACK-10104?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16313377#comment-16313377
] 

ASF GitHub Bot commented on CLOUDSTACK-10104:
---------------------------------------------

rhtyd closed pull request #2282: CLOUDSTACK-10104:Optimize database transactions in ListDomain
API to improve performance
URL: https://github.com/apache/cloudstack/pull/2282
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/api/src/com/cloud/user/ResourceLimitService.java b/api/src/com/cloud/user/ResourceLimitService.java
index 0ec2dc1c758..aee2e1515e5 100644
--- a/api/src/com/cloud/user/ResourceLimitService.java
+++ b/api/src/com/cloud/user/ResourceLimitService.java
@@ -104,6 +104,14 @@
      */
     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 static long findCorrectResourceLimit(Long limit, long accountId,
Resource
         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 static DomainVO findDomainById(Long domainId) {
         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 2a6919bcf71..1c9890f2269 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -1890,8 +1890,7 @@
             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 @@
         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 @@
 
         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 @@
 
 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 @@ else if (vr.getFormat() == ImageFormat.OVA){
         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){
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 DomainResponse newDomainResponse(ResponseView view, EnumSet<DomainDetails
         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 DomainResponse newDomainResponse(ResponseView view, EnumSet<DomainDetails
             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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 void setResourceLimits(DomainJoinVO domain, boolean fullView, ResourceLim
         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 @@
     @Column(name="secondaryStorageTotal")
     private Long secondaryStorageTotal;
 
+    @Transient
+    private String parentName;
+
+    @Transient
+    private String parentUuid;
+
     public DomainJoinVO() {
     }
 
@@ -498,4 +506,33 @@ public void setSecondaryStorageLimit(Long secondaryStorageLimit) {
         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);
+        }
+
+    };
 }
diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
index 05a2c97333e..1815c60c71b 100644
--- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@ -410,6 +410,17 @@ public long findCorrectResourceLimitForDomain(Domain domain, ResourceType
type)
         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 d2d7c3313e0..2bdc0d6f195 100644
--- a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java
@@ -86,6 +86,11 @@ public long findCorrectResourceLimitForDomain(Domain domain, ResourceType
type)
         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 00047bf5c2e..42062a17a55 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 @@
                                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 @@ def test_LoginApiUuidResponse(self):
         )
         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):


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> Optimize database transactions in ListDomain API to improve performance
> -----------------------------------------------------------------------
>
>                 Key: CLOUDSTACK-10104
>                 URL: https://issues.apache.org/jira/browse/CLOUDSTACK-10104
>             Project: CloudStack
>          Issue Type: Bug
>      Security Level: Public(Anyone can view this level - this is the default.) 
>          Components: API
>            Reporter: Pranali Mande
>
> 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 for in the main fetch query, which is causing the
response to slow down. The database transactions could be optimized to reduce the response
time of the Listdomain API



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Mime
View raw message