You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ki...@apache.org on 2013/01/28 13:22:52 UTC

[12/50] [abbrv] git commit: CLOUDSTACK-355: create DB view for ZoneResponse to fix count for listZonesByCmd.

CLOUDSTACK-355: create DB view for ZoneResponse to fix count for
listZonesByCmd.


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/26be5ce2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/26be5ce2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/26be5ce2

Branch: refs/heads/regions
Commit: 26be5ce2dfd00dd8a4ea3272ad7da2be6d060c5c
Parents: afb2770
Author: Min Chen <mi...@citrix.com>
Authored: Tue Jan 22 16:39:17 2013 -0800
Committer: Min Chen <mi...@citrix.com>
Committed: Tue Jan 22 16:39:45 2013 -0800

----------------------------------------------------------------------
 api/src/com/cloud/server/ManagementService.java    |   10 -
 .../api/command/user/zone/ListZonesByCmd.java      |   13 +-
 .../cloudstack/api/response/ZoneResponse.java      |    6 +-
 .../org/apache/cloudstack/query/QueryService.java  |    4 +
 server/src/com/cloud/api/ApiDBUtils.java           |   14 +
 server/src/com/cloud/api/ApiResponseHelper.java    |   94 ++----
 server/src/com/cloud/api/ApiServer.java            |    2 +
 .../src/com/cloud/api/query/QueryManagerImpl.java  |  138 +++++++
 .../com/cloud/api/query/ViewResponseHelper.java    |   10 +
 .../com/cloud/api/query/dao/DataCenterJoinDao.java |   30 ++
 .../cloud/api/query/dao/DataCenterJoinDaoImpl.java |  109 ++++++
 .../com/cloud/api/query/vo/DataCenterJoinVO.java   |  284 +++++++++++++++
 .../configuration/DefaultComponentLibrary.java     |    2 +
 .../src/com/cloud/server/ManagementServerImpl.java |  112 ------
 setup/db/create-schema-view.sql                    |   29 ++
 setup/db/db/schema-40to410.sql                     |   29 ++
 16 files changed, 687 insertions(+), 199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/api/src/com/cloud/server/ManagementService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java
index 3bc7f93..32c2b05 100755
--- a/api/src/com/cloud/server/ManagementService.java
+++ b/api/src/com/cloud/server/ManagementService.java
@@ -94,16 +94,6 @@ public interface ManagementService {
     static final String Name = "management-server";
 
     /**
-     * Retrieves the list of data centers with search criteria. Currently the only search criteria is "available" zones
-     * for the
-     * account that invokes the API. By specifying available=true all zones which the account can access. By specifying
-     * available=false the zones where the account has virtual machine instances will be returned.
-     *
-     * @return a list of DataCenters
-     */
-    List<? extends DataCenter> listDataCenters(ListZonesByCmd cmd);
-
-    /**
      * returns the a map of the names/values in the configuraton table
      *
      * @return map of configuration name/values

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java
index 5f5f9e7..ccacf06 100644
--- a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java
@@ -27,6 +27,7 @@ import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseListCmd;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import com.cloud.dc.DataCenter;
 
@@ -86,16 +87,8 @@ public class ListZonesByCmd extends BaseListCmd {
 
     @Override
     public void execute(){
-        List<? extends DataCenter> dataCenters = _mgr.listDataCenters(this);
-        ListResponse<ZoneResponse> response = new ListResponse<ZoneResponse>();
-        List<ZoneResponse> zoneResponses = new ArrayList<ZoneResponse>();
-        for (DataCenter dataCenter : dataCenters) {
-            ZoneResponse zoneResponse = _responseGenerator.createZoneResponse(dataCenter, showCapacities);
-            zoneResponse.setObjectName("zone");
-            zoneResponses.add(zoneResponse);
-        }
-
-        response.setResponses(zoneResponses);
+
+        ListResponse<ZoneResponse> response = _queryService.listDataCenters(this);
         response.setResponseName(getCommandName());
         this.setResponseObject(response);
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
index 72e0bb2..ca1cb57 100644
--- a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
@@ -65,8 +65,8 @@ public class ZoneResponse extends BaseResponse {
     @SerializedName(ApiConstants.DOMAIN) @Param(description="Network domain name for the networks in the zone")
     private String domain;
 
-    @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the ID of the containing domain, null for public zones")
-    private Long domainId;
+    @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the UUID of the containing domain, null for public zones")
+    private String domainId;
 
     @SerializedName("domainname") @Param(description="the name of the containing domain, null for public zones")
     private String domainName;
@@ -140,7 +140,7 @@ public class ZoneResponse extends BaseResponse {
         this.domain = domain;
     }
 
-    public void setDomainId(Long domainId) {
+    public void setDomainId(String domainId) {
         this.domainId = domainId;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/api/src/org/apache/cloudstack/query/QueryService.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java
index add9d23..f3f6d3d 100644
--- a/api/src/org/apache/cloudstack/query/QueryService.java
+++ b/api/src/org/apache/cloudstack/query/QueryService.java
@@ -35,6 +35,7 @@ import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
 import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
 import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
 import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
 import org.apache.cloudstack.api.response.AccountResponse;
 import org.apache.cloudstack.api.response.AsyncJobResponse;
 import org.apache.cloudstack.api.response.DiskOfferingResponse;
@@ -53,6 +54,7 @@ import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
 
 
 
@@ -100,4 +102,6 @@ public interface QueryService {
     public ListResponse<DiskOfferingResponse>  searchForDiskOfferings(ListDiskOfferingsCmd cmd);
 
     public ListResponse<ServiceOfferingResponse>  searchForServiceOfferings(ListServiceOfferingsCmd cmd);
+
+    public ListResponse<ZoneResponse>  listDataCenters(ListZonesByCmd cmd);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index 9b88664..0b08b26 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -41,9 +41,11 @@ import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
 
 import com.cloud.api.query.dao.AccountJoinDao;
 import com.cloud.api.query.dao.AsyncJobJoinDao;
+import com.cloud.api.query.dao.DataCenterJoinDao;
 import com.cloud.api.query.dao.DiskOfferingJoinDao;
 import com.cloud.api.query.dao.DomainRouterJoinDao;
 import com.cloud.api.query.dao.HostJoinDao;
@@ -60,6 +62,7 @@ import com.cloud.api.query.dao.UserVmJoinDao;
 import com.cloud.api.query.dao.VolumeJoinDao;
 import com.cloud.api.query.vo.AccountJoinVO;
 import com.cloud.api.query.vo.AsyncJobJoinVO;
+import com.cloud.api.query.vo.DataCenterJoinVO;
 import com.cloud.api.query.vo.DiskOfferingJoinVO;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
 import com.cloud.api.query.vo.EventJoinVO;
@@ -88,6 +91,7 @@ import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.dc.AccountVlanMapVO;
 import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.HostPodVO;
 import com.cloud.dc.Vlan;
@@ -342,6 +346,7 @@ public class ApiDBUtils {
     private static AsyncJobJoinDao _jobJoinDao;
     private static DiskOfferingJoinDao _diskOfferingJoinDao;
     private static ServiceOfferingJoinDao _srvOfferingJoinDao;
+    private static DataCenterJoinDao _dcJoinDao;
 
     private static PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
     private static PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@@ -448,6 +453,7 @@ public class ApiDBUtils {
         _asyncJobDao = locator.getDao(AsyncJobDao.class);
         _diskOfferingJoinDao = locator.getDao(DiskOfferingJoinDao.class);
         _srvOfferingJoinDao = locator.getDao(ServiceOfferingJoinDao.class);
+        _dcJoinDao = locator.getDao(DataCenterJoinDao.class);
 
         // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned
         _statsCollector = StatsCollector.getInstance();
@@ -1426,4 +1432,12 @@ public class ApiDBUtils {
    public static ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering){
        return _srvOfferingJoinDao.newServiceOfferingView(offering);
    }
+
+   public static ZoneResponse newDataCenterResponse(DataCenterJoinVO dc, Boolean showCapacities) {
+       return _dcJoinDao.newDataCenterResponse(dc, showCapacities);
+   }
+
+   public static DataCenterJoinVO newDataCenterView(DataCenter dc){
+       return _dcJoinDao.newDataCenterView(dc);
+   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 1965f33..1c8849a 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -44,6 +44,7 @@ import com.cloud.api.query.ViewResponseHelper;
 import com.cloud.api.query.vo.AccountJoinVO;
 import com.cloud.api.query.vo.AsyncJobJoinVO;
 import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.api.query.vo.DataCenterJoinVO;
 import com.cloud.api.query.vo.DiskOfferingJoinVO;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
 import com.cloud.api.query.vo.EventJoinVO;
@@ -717,77 +718,42 @@ public class ApiResponseHelper implements ResponseGenerator {
 
     @Override
     public ZoneResponse createZoneResponse(DataCenter dataCenter, Boolean showCapacities) {
-        Account account = UserContext.current().getCaller();
-        ZoneResponse zoneResponse = new ZoneResponse();
-        zoneResponse.setId(dataCenter.getUuid());
-        zoneResponse.setName(dataCenter.getName());
-        zoneResponse.setSecurityGroupsEnabled(ApiDBUtils.isSecurityGroupEnabledInZone(dataCenter.getId()));
-        zoneResponse.setLocalStorageEnabled(dataCenter.isLocalStorageEnabled());
-
-        if ((dataCenter.getDescription() != null) && !dataCenter.getDescription().equalsIgnoreCase("null")) {
-            zoneResponse.setDescription(dataCenter.getDescription());
-        }
-
-        if ((account == null) || (account.getType() == Account.ACCOUNT_TYPE_ADMIN)) {
-            zoneResponse.setDns1(dataCenter.getDns1());
-            zoneResponse.setDns2(dataCenter.getDns2());
-            zoneResponse.setInternalDns1(dataCenter.getInternalDns1());
-            zoneResponse.setInternalDns2(dataCenter.getInternalDns2());
-            // FIXME zoneResponse.setVlan(dataCenter.get.getVnet());
-            zoneResponse.setGuestCidrAddress(dataCenter.getGuestNetworkCidr());
-        }
+        DataCenterJoinVO vOffering = ApiDBUtils.newDataCenterView(dataCenter);
+        return ApiDBUtils.newDataCenterResponse(vOffering, showCapacities);
+    }
 
-        if (showCapacities != null && showCapacities) {
-            List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(dataCenter.getId(), null, null);
-            Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
-            float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor();
+    public static List<CapacityResponse> getDataCenterCapacityResponse(Long zoneId){
+        List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(zoneId, null, null);
+        Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
+        float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor();
 
-            for (SummedCapacity capacity : capacities) {
-                CapacityResponse capacityResponse = new CapacityResponse();
-                capacityResponse.setCapacityType(capacity.getCapacityType());
-                capacityResponse.setCapacityUsed(capacity.getUsedCapacity());
-                if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) {
-                    capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor)));
-                } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
-                    List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(dataCenter.getId(), null, null);
-                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
-                    capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
-                } else {
-                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
-                }
-                if (capacityResponse.getCapacityTotal() != 0) {
-                    capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f));
-                } else {
-                    capacityResponse.setPercentUsed(s_percentFormat.format(0L));
-                }
-                capacityResponses.add(capacityResponse);
+        for (SummedCapacity capacity : capacities) {
+            CapacityResponse capacityResponse = new CapacityResponse();
+            capacityResponse.setCapacityType(capacity.getCapacityType());
+            capacityResponse.setCapacityUsed(capacity.getUsedCapacity());
+            if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) {
+                capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor)));
+            } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
+                List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(zoneId, null, null);
+                capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
+                capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
+            } else {
+                capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
             }
-            // Do it for stats as well.
-            capacityResponses.addAll(getStatsCapacityresponse(null, null, null, dataCenter.getId()));
-
-            zoneResponse.setCapacitites(new ArrayList<CapacityResponse>(capacityResponses));
-        }
-
-        // set network domain info
-        zoneResponse.setDomain(dataCenter.getDomain());
-
-        // set domain info
-        Long domainId = dataCenter.getDomainId();
-        if (domainId != null) {
-            Domain domain = ApiDBUtils.findDomainById(domainId);
-            zoneResponse.setDomainId(domain.getId());
-            zoneResponse.setDomainName(domain.getName());
+            if (capacityResponse.getCapacityTotal() != 0) {
+                capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f));
+            } else {
+                capacityResponse.setPercentUsed(s_percentFormat.format(0L));
+            }
+            capacityResponses.add(capacityResponse);
         }
+        // Do it for stats as well.
+        capacityResponses.addAll(getStatsCapacityresponse(null, null, null, zoneId));
 
-        zoneResponse.setType(dataCenter.getNetworkType().toString());
-        zoneResponse.setAllocationState(dataCenter.getAllocationState().toString());
-        zoneResponse.setZoneToken(dataCenter.getZoneToken());
-        zoneResponse.setDhcpProvider(dataCenter.getDhcpProvider());
-        zoneResponse.setObjectName("zone");
-        return zoneResponse;
+        return new ArrayList<CapacityResponse>(capacityResponses);
     }
 
-    private List<CapacityResponse> getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) {
+    private static List<CapacityResponse> getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) {
         List<CapacityVO> capacities = new ArrayList<CapacityVO>();
         capacities.add(ApiDBUtils.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId));
         if (clusterId == null && podId == null) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index ad2a12f..ed27200 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -61,6 +61,7 @@ import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
 import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
 import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
 import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.http.client.utils.URLEncodedUtils;
 import org.apache.http.ConnectionClosedException;
@@ -518,6 +519,7 @@ public class ApiServer implements HttpRequestHandler {
                     && !(cmdObj instanceof ListStoragePoolsCmd)
                     && !(cmdObj instanceof ListDiskOfferingsCmd)
                     && !(cmdObj instanceof ListServiceOfferingsCmd)
+                    && !(cmdObj instanceof ListZonesByCmd)
                     ) {
                 buildAsyncListResponse((BaseListCmd) cmdObj, caller);
             }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
index ee47296..a943776 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -18,8 +18,11 @@ package com.cloud.api.query;
 
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
@@ -41,6 +44,7 @@ import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
 import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
 import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
 import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
 import org.apache.cloudstack.api.response.AccountResponse;
 import org.apache.cloudstack.api.response.AsyncJobResponse;
 import org.apache.cloudstack.api.response.DiskOfferingResponse;
@@ -59,11 +63,13 @@ import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.query.QueryService;
 import org.apache.log4j.Logger;
 
 import com.cloud.api.query.dao.AccountJoinDao;
 import com.cloud.api.query.dao.AsyncJobJoinDao;
+import com.cloud.api.query.dao.DataCenterJoinDao;
 import com.cloud.api.query.dao.DiskOfferingJoinDao;
 import com.cloud.api.query.dao.DomainRouterJoinDao;
 import com.cloud.api.query.dao.HostJoinDao;
@@ -80,6 +86,7 @@ import com.cloud.api.query.dao.UserVmJoinDao;
 import com.cloud.api.query.dao.VolumeJoinDao;
 import com.cloud.api.query.vo.AccountJoinVO;
 import com.cloud.api.query.vo.AsyncJobJoinVO;
+import com.cloud.api.query.vo.DataCenterJoinVO;
 import com.cloud.api.query.vo.DiskOfferingJoinVO;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
 import com.cloud.api.query.vo.EventJoinVO;
@@ -96,6 +103,7 @@ import com.cloud.api.query.vo.UserAccountJoinVO;
 import com.cloud.api.query.vo.UserVmJoinVO;
 import com.cloud.api.query.vo.VolumeJoinVO;
 import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.DataCenterVO;
 import com.cloud.domain.Domain;
 import com.cloud.domain.DomainVO;
 import com.cloud.domain.dao.DomainDao;
@@ -107,6 +115,7 @@ import com.cloud.ha.HighAvailabilityManager;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.network.security.SecurityGroupVMMapVO;
 import com.cloud.network.security.dao.SecurityGroupVMMapDao;
+import com.cloud.org.Grouping;
 import com.cloud.projects.ProjectInvitation;
 import com.cloud.projects.Project.ListProjectResourcesCriteria;
 import com.cloud.projects.Project;
@@ -135,8 +144,10 @@ import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.SearchCriteria.Func;
 import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.UserVmDao;
 
 /**
@@ -234,6 +245,12 @@ public class QueryManagerImpl implements QueryService, Manager {
     private ServiceOfferingDao _srvOfferingDao;
 
     @Inject
+    private DataCenterJoinDao _dcJoinDao;
+
+    @Inject
+    private DomainRouterDao _routerDao;
+
+    @Inject
     private HighAvailabilityManager _haMgr;
 
     @Override
@@ -2187,6 +2204,125 @@ public class QueryManagerImpl implements QueryService, Manager {
 
 
 
+    @Override
+    public ListResponse<ZoneResponse> listDataCenters(ListZonesByCmd cmd) {
+        Pair<List<DataCenterJoinVO>, Integer> result = listDataCentersInternal(cmd);
+        ListResponse<ZoneResponse> response = new ListResponse<ZoneResponse>();
+        List<ZoneResponse> dcResponses = ViewResponseHelper.createDataCenterResponse(cmd.getShowCapacities(), result.first().toArray(new DataCenterJoinVO[result.first().size()]));
+        response.setResponses(dcResponses, result.second());
+        return response;
+    }
+
+
+    private Pair<List<DataCenterJoinVO>, Integer> listDataCentersInternal(ListZonesByCmd cmd) {
+        Account account = UserContext.current().getCaller();
+        Long domainId = cmd.getDomainId();
+        Long id = cmd.getId();
+        String keyword = cmd.getKeyword();
+
+        Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchCriteria<DataCenterJoinVO> sc = _dcJoinDao.createSearchCriteria();
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        } else {
+            if (keyword != null) {
+                SearchCriteria<DataCenterJoinVO> ssc = _dcJoinDao.createSearchCriteria();
+                ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+                ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+                sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+            }
+
+            if (domainId != null) {
+                // for domainId != null
+                // right now, we made the decision to only list zones associated
+                // with this domain, private zone
+                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
+            }  else if (account.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                // it was decided to return all zones for the user's domain, and
+                // everything above till root
+                // list all zones belonging to this domain, and all of its
+                // parents
+                // check the parent, if not null, add zones for that parent to
+                // list
+
+
+                // find all domain Id up to root domain for this account
+                List<Long> domainIds = new ArrayList<Long>();
+                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
+                if ( domainRecord == null ){
+                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
+                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
+                }
+                domainIds.add(domainRecord.getId());
+                while (domainRecord.getParent() != null ){
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                    domainIds.add(domainRecord.getId());
+                }
+                // domainId == null (public zones) or domainId IN [all domain id up to root domain]
+                SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
+                sdc.addOr("domainIdIn", SearchCriteria.Op.IN, domainIds);
+                sdc.addOr("domainId", SearchCriteria.Op.NULL);
+                sc.addAnd("domain", SearchCriteria.Op.SC, sdc);
+
+                // remove disabled zones
+                sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
+
+            } else if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+                // it was decided to return all zones for the domain admin, and
+                // everything above till root, as well as zones till the domain leaf
+                List<Long> domainIds = new ArrayList<Long>();
+                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
+                if ( domainRecord == null ){
+                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
+                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
+                }
+                domainIds.add(domainRecord.getId());
+                // find all domain Ids till leaf
+                List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId());
+                for (DomainVO domain : allChildDomains) {
+                    domainIds.add(domain.getId());
+                }
+                // then find all domain Id up to root domain for this account
+                while (domainRecord.getParent() != null ){
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                    domainIds.add(domainRecord.getId());
+                }
+
+                // domainId == null (public zones) or domainId IN [all domain id up to root domain]
+                SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
+                sdc.addOr("domainIdIn", SearchCriteria.Op.IN, domainIds);
+                sdc.addOr("domainId", SearchCriteria.Op.NULL);
+                sc.addAnd("domain", SearchCriteria.Op.SC, sdc);
+
+                // remove disabled zones
+                sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
+            }
+
+            // handle available=FALSE option, only return zones with at least one VM running there
+            Boolean available = cmd.isAvailable();
+            if (account != null) {
+                if ((available != null) && Boolean.FALSE.equals(available)) {
+                    Set<Long> dcIds = new HashSet<Long>(); //data centers with at least one VM running
+                    List<DomainRouterVO> routers = _routerDao.listBy(account.getId());
+                    for (DomainRouterVO router : routers){
+                        dcIds.add(router.getDataCenterIdToDeployIn());
+                    }
+                    if ( dcIds.size() == 0) {
+                        return new Pair<List<DataCenterJoinVO>, Integer>(new ArrayList<DataCenterJoinVO>(), 0);
+                    }
+                    else{
+                        sc.addAnd("idIn", SearchCriteria.Op.IN, dcIds);
+                    }
+
+                }
+            }
+        }
+
+        return _dcJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+
     // This method is used for permissions check for both disk and service
     // offerings
     private boolean isPermissible(Long accountDomainId, Long offeringDomainId) {
@@ -2214,4 +2350,6 @@ public class QueryManagerImpl implements QueryService, Manager {
 
         return false;
     }
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/query/ViewResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java
index dfccdce..55d84bb 100644
--- a/server/src/com/cloud/api/query/ViewResponseHelper.java
+++ b/server/src/com/cloud/api/query/ViewResponseHelper.java
@@ -40,11 +40,13 @@ import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.log4j.Logger;
 
 import com.cloud.api.ApiDBUtils;
 import com.cloud.api.query.vo.AccountJoinVO;
 import com.cloud.api.query.vo.AsyncJobJoinVO;
+import com.cloud.api.query.vo.DataCenterJoinVO;
 import com.cloud.api.query.vo.DiskOfferingJoinVO;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
 import com.cloud.api.query.vo.EventJoinVO;
@@ -294,4 +296,12 @@ public class ViewResponseHelper {
         }
         return respList;
     }
+
+    public static List<ZoneResponse> createDataCenterResponse(Boolean showCapacities, DataCenterJoinVO... dcs) {
+        List<ZoneResponse> respList = new ArrayList<ZoneResponse>();
+        for (DataCenterJoinVO vt : dcs){
+            respList.add(ApiDBUtils.newDataCenterResponse(vt, showCapacities));
+        }
+        return respList;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/query/dao/DataCenterJoinDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/DataCenterJoinDao.java b/server/src/com/cloud/api/query/dao/DataCenterJoinDao.java
new file mode 100644
index 0000000..340f86f
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/DataCenterJoinDao.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api.query.dao;
+
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.api.query.vo.DataCenterJoinVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.utils.db.GenericDao;
+
+public interface DataCenterJoinDao extends GenericDao<DataCenterJoinVO, Long> {
+
+    ZoneResponse newDataCenterResponse(DataCenterJoinVO dof, Boolean showCapacities);
+
+    DataCenterJoinVO newDataCenterView(DataCenter dof);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
new file mode 100644
index 0000000..4ef182b
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
@@ -0,0 +1,109 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api.query.dao;
+
+import java.util.List;
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.ApiResponseHelper;
+import com.cloud.api.query.vo.DataCenterJoinVO;
+import com.cloud.dc.DataCenter;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+
+@Local(value={DataCenterJoinDao.class})
+public class DataCenterJoinDaoImpl extends GenericDaoBase<DataCenterJoinVO, Long> implements DataCenterJoinDao {
+    public static final Logger s_logger = Logger.getLogger(DataCenterJoinDaoImpl.class);
+
+
+    private SearchBuilder<DataCenterJoinVO> dofIdSearch;
+
+    protected DataCenterJoinDaoImpl() {
+
+        dofIdSearch = createSearchBuilder();
+        dofIdSearch.and("id", dofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        dofIdSearch.done();
+
+        this._count = "select count(distinct id) from data_center_view WHERE ";
+    }
+
+
+
+    @Override
+    public ZoneResponse newDataCenterResponse(DataCenterJoinVO dataCenter, Boolean showCapacities) {
+
+        Account account = UserContext.current().getCaller();
+        ZoneResponse zoneResponse = new ZoneResponse();
+        zoneResponse.setId(dataCenter.getUuid());
+        zoneResponse.setName(dataCenter.getName());
+        zoneResponse.setSecurityGroupsEnabled(ApiDBUtils.isSecurityGroupEnabledInZone(dataCenter.getId()));
+        zoneResponse.setLocalStorageEnabled(dataCenter.isLocalStorageEnabled());
+
+        if ((dataCenter.getDescription() != null) && !dataCenter.getDescription().equalsIgnoreCase("null")) {
+            zoneResponse.setDescription(dataCenter.getDescription());
+        }
+
+        if ((account == null) || (account.getType() == Account.ACCOUNT_TYPE_ADMIN)) {
+            zoneResponse.setDns1(dataCenter.getDns1());
+            zoneResponse.setDns2(dataCenter.getDns2());
+            zoneResponse.setInternalDns1(dataCenter.getInternalDns1());
+            zoneResponse.setInternalDns2(dataCenter.getInternalDns2());
+            // FIXME zoneResponse.setVlan(dataCenter.get.getVnet());
+            zoneResponse.setGuestCidrAddress(dataCenter.getGuestNetworkCidr());
+        }
+
+        if (showCapacities != null && showCapacities) {
+            zoneResponse.setCapacitites(ApiResponseHelper.getDataCenterCapacityResponse(dataCenter.getId()));
+        }
+
+        // set network domain info
+        zoneResponse.setDomain(dataCenter.getDomain());
+
+        // set domain info
+
+        zoneResponse.setDomainId(dataCenter.getDomainUuid());
+        zoneResponse.setDomainName(dataCenter.getDomainName());
+
+        zoneResponse.setType(dataCenter.getNetworkType().toString());
+        zoneResponse.setAllocationState(dataCenter.getAllocationState().toString());
+        zoneResponse.setZoneToken(dataCenter.getZoneToken());
+        zoneResponse.setDhcpProvider(dataCenter.getDhcpProvider());
+        zoneResponse.setObjectName("zone");
+        return zoneResponse;
+    }
+
+
+    @Override
+    public DataCenterJoinVO newDataCenterView(DataCenter dataCenter) {
+        SearchCriteria<DataCenterJoinVO> sc = dofIdSearch.create();
+        sc.setParameters("id", dataCenter.getId());
+        List<DataCenterJoinVO> dcs = searchIncludingRemoved(sc, null, null, false);
+        assert dcs != null && dcs.size() == 1 : "No data center found for data center id " + dataCenter.getId();
+        return dcs.get(0);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/api/query/vo/DataCenterJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/DataCenterJoinVO.java b/server/src/com/cloud/api/query/vo/DataCenterJoinVO.java
new file mode 100644
index 0000000..67a3f27
--- /dev/null
+++ b/server/src/com/cloud/api/query/vo/DataCenterJoinVO.java
@@ -0,0 +1,284 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api.query.vo;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.org.Grouping.AllocationState;
+import com.cloud.utils.db.GenericDao;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+@Entity
+@Table(name="data_center_view")
+public class DataCenterJoinVO extends BaseViewVO implements InternalIdentity, Identity {
+
+    @Id
+    @Column(name="id")
+    private long id;
+
+    @Column(name="uuid")
+    private String uuid;
+
+    @Column(name="name")
+    private String name;
+
+    @Column(name="description")
+    private String description = null;
+
+    @Column(name="dns1")
+    private String dns1 = null;
+
+    @Column(name="dns2")
+    private String dns2 = null;
+
+    @Column(name="internal_dns1")
+    private String internalDns1 = null;
+
+    @Column(name="internal_dns2")
+    private String internalDns2 = null;
+
+    @Column(name="guest_network_cidr")
+    private String guestNetworkCidr = null;
+
+    @Column(name="domain")
+    private String domain;
+
+    @Column(name="networktype")
+    @Enumerated(EnumType.STRING)
+    NetworkType networkType;
+
+    @Column(name="dhcp_provider")
+    private String dhcpProvider;
+
+    @Column(name="zone_token")
+    private String zoneToken;
+
+    @Column(name="allocation_state")
+    @Enumerated(value=EnumType.STRING)
+    AllocationState allocationState;
+
+    @Column(name="is_security_group_enabled")
+    boolean securityGroupEnabled;
+
+    @Column(name="is_local_storage_enabled")
+    boolean localStorageEnabled;
+
+    @Column(name=GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name="domain_id")
+    private long domainId;
+
+    @Column(name="domain_uuid")
+    private String domainUuid;
+
+    @Column(name="domain_name")
+    private String domainName;
+
+    @Column(name="domain_path")
+    private String domainPath;
+
+
+    public DataCenterJoinVO() {
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getDns1() {
+        return dns1;
+    }
+
+    public void setDns1(String dns1) {
+        this.dns1 = dns1;
+    }
+
+    public String getDns2() {
+        return dns2;
+    }
+
+    public void setDns2(String dns2) {
+        this.dns2 = dns2;
+    }
+
+    public String getInternalDns1() {
+        return internalDns1;
+    }
+
+    public void setInternalDns1(String internalDns1) {
+        this.internalDns1 = internalDns1;
+    }
+
+    public String getInternalDns2() {
+        return internalDns2;
+    }
+
+    public void setInternalDns2(String internalDns2) {
+        this.internalDns2 = internalDns2;
+    }
+
+    public String getGuestNetworkCidr() {
+        return guestNetworkCidr;
+    }
+
+    public void setGuestNetworkCidr(String guestNetworkCidr) {
+        this.guestNetworkCidr = guestNetworkCidr;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public NetworkType getNetworkType() {
+        return networkType;
+    }
+
+    public void setNetworkType(NetworkType networkType) {
+        this.networkType = networkType;
+    }
+
+    public String getDhcpProvider() {
+        return dhcpProvider;
+    }
+
+    public void setDhcpProvider(String dhcpProvider) {
+        this.dhcpProvider = dhcpProvider;
+    }
+
+    public String getZoneToken() {
+        return zoneToken;
+    }
+
+    public void setZoneToken(String zoneToken) {
+        this.zoneToken = zoneToken;
+    }
+
+    public AllocationState getAllocationState() {
+        return allocationState;
+    }
+
+    public void setAllocationState(AllocationState allocationState) {
+        this.allocationState = allocationState;
+    }
+
+    public boolean isSecurityGroupEnabled() {
+        return securityGroupEnabled;
+    }
+
+    public void setSecurityGroupEnabled(boolean securityGroupEnabled) {
+        this.securityGroupEnabled = securityGroupEnabled;
+    }
+
+
+    public boolean isLocalStorageEnabled() {
+        return localStorageEnabled;
+    }
+
+    public void setLocalStorageEnabled(boolean localStorageEnabled) {
+        this.localStorageEnabled = localStorageEnabled;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    public long getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(long domainId) {
+        this.domainId = domainId;
+    }
+
+    public String getDomainUuid() {
+        return domainUuid;
+    }
+
+    public void setDomainUuid(String domainUuid) {
+        this.domainUuid = domainUuid;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+    public String getDomainPath() {
+        return domainPath;
+    }
+
+    public void setDomainPath(String domainPath) {
+        this.domainPath = domainPath;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/configuration/DefaultComponentLibrary.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
index 9652586..98da7ad 100755
--- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java
+++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
@@ -27,6 +27,7 @@ import com.cloud.alert.dao.AlertDaoImpl;
 import com.cloud.api.query.QueryManagerImpl;
 import com.cloud.api.query.dao.AccountJoinDaoImpl;
 import com.cloud.api.query.dao.AsyncJobJoinDaoImpl;
+import com.cloud.api.query.dao.DataCenterJoinDaoImpl;
 import com.cloud.api.query.dao.DiskOfferingJoinDaoImpl;
 import com.cloud.api.query.dao.ServiceOfferingJoinDaoImpl;
 import com.cloud.api.query.dao.DomainRouterJoinDaoImpl;
@@ -396,6 +397,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
         addDao("StoragePoolJoinDao", StoragePoolJoinDaoImpl.class);
         addDao("DiskOfferingJoinDao", DiskOfferingJoinDaoImpl.class);
         addDao("ServiceOfferingJoinDao", ServiceOfferingJoinDaoImpl.class);
+        addDao("DataCenterJoinDao", DataCenterJoinDaoImpl.class);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 8182421..a2a74c2 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -416,119 +416,7 @@ public class ManagementServerImpl implements ManagementServer {
         return PasswordGenerator.generateRandomPassword(6);
     }
 
-    @Override
-    public List<DataCenterVO> listDataCenters(ListZonesByCmd cmd) {
-        Account account = UserContext.current().getCaller();
-        List<DataCenterVO> dcs = null;
-        Long domainId = cmd.getDomainId();
-        Long id = cmd.getId();
-        boolean removeDisabledZones = false;
-        String keyword = cmd.getKeyword();
-        if (domainId != null) {
-            // for domainId != null
-            // right now, we made the decision to only list zones associated
-            // with this domain
-            dcs = _dcDao.findZonesByDomainId(domainId, keyword); // private
-                                                                 // zones
-        } else if ((account == null || account.getType() == Account.ACCOUNT_TYPE_ADMIN)) {
-            if (keyword != null) {
-                dcs = _dcDao.findByKeyword(keyword);
-            } else {
-                dcs = _dcDao.listAll(); // all zones
-            }
-        } else if (account.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-            // it was decided to return all zones for the user's domain, and
-            // everything above till root
-            // list all zones belonging to this domain, and all of its parents
-            // check the parent, if not null, add zones for that parent to list
-            dcs = new ArrayList<DataCenterVO>();
-            DomainVO domainRecord = _domainDao.findById(account.getDomainId());
-            if (domainRecord != null) {
-                while (true) {
-                    dcs.addAll(_dcDao.findZonesByDomainId(domainRecord.getId(), keyword));
-                    if (domainRecord.getParent() != null) {
-                        domainRecord = _domainDao.findById(domainRecord.getParent());
-                    } else {
-                        break;
-                    }
-                }
-            }
-            // add all public zones too
-            dcs.addAll(_dcDao.listPublicZones(keyword));
-            removeDisabledZones = true;
-        } else if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-            // it was decided to return all zones for the domain admin, and
-            // everything above till root
-            dcs = new ArrayList<DataCenterVO>();
-            DomainVO domainRecord = _domainDao.findById(account.getDomainId());
-            // this covers path till root
-            if (domainRecord != null) {
-                DomainVO localRecord = domainRecord;
-                while (true) {
-                    dcs.addAll(_dcDao.findZonesByDomainId(localRecord.getId(), keyword));
-                    if (localRecord.getParent() != null) {
-                        localRecord = _domainDao.findById(localRecord.getParent());
-                    } else {
-                        break;
-                    }
-                }
-            }
-            // this covers till leaf
-            if (domainRecord != null) {
-                // find all children for this domain based on a like search by
-                // path
-                List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId());
-                List<Long> allChildDomainIds = new ArrayList<Long>();
-                // create list of domainIds for search
-                for (DomainVO domain : allChildDomains) {
-                    allChildDomainIds.add(domain.getId());
-                }
-                // now make a search for zones based on this
-                if (allChildDomainIds.size() > 0) {
-                    List<DataCenterVO> childZones = _dcDao.findChildZones((allChildDomainIds.toArray()), keyword);
-                    dcs.addAll(childZones);
-                }
-            }
-            // add all public zones too
-            dcs.addAll(_dcDao.listPublicZones(keyword));
-            removeDisabledZones = true;
-        }
-
-        if (removeDisabledZones) {
-            dcs.removeAll(_dcDao.listDisabledZones());
-        }
-
-        Boolean available = cmd.isAvailable();
-        if (account != null) {
-            if ((available != null) && Boolean.FALSE.equals(available)) {
-                List<DomainRouterVO> routers = _routerDao.listBy(account.getId());
-                for (Iterator<DataCenterVO> iter = dcs.iterator(); iter.hasNext();) {
-                    DataCenterVO dc = iter.next();
-                    boolean found = false;
-                    for (DomainRouterVO router : routers) {
-                        if (dc.getId() == router.getDataCenterIdToDeployIn()) {
-                            found = true;
-                            break;
-                        }
-                    }
-                    if (!found) {
-                        iter.remove();
-                    }
-                }
-            }
-        }
 
-        if (id != null) {
-            List<DataCenterVO> singleZone = new ArrayList<DataCenterVO>();
-            for (DataCenterVO zone : dcs) {
-                if (zone.getId() == id) {
-                    singleZone.add(zone);
-                }
-            }
-            return singleZone;
-        }
-        return dcs;
-    }
 
     @Override
     public HostVO getHostBy(long hostId) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/setup/db/create-schema-view.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema-view.sql b/setup/db/create-schema-view.sql
index f5c0591..f68a6ca 100644
--- a/setup/db/create-schema-view.sql
+++ b/setup/db/create-schema-view.sql
@@ -1105,3 +1105,32 @@ CREATE VIEW `cloud`.`service_offering_view` AS
         `cloud`.`disk_offering` ON service_offering.id = disk_offering.id
             left join
         `cloud`.`domain` ON disk_offering.domain_id = domain.id;
+
+DROP VIEW IF EXISTS `cloud`.`data_center_view`;
+CREATE VIEW `cloud`.`data_center_view` AS
+    select 
+        data_center.id,
+        data_center.uuid,
+        data_center.name,
+        data_center.is_security_group_enabled,
+        data_center.is_local_storage_enabled,
+        data_center.description,
+        data_center.dns1,
+        data_center.dns2,
+        data_center.internal_dns1,
+        data_center.internal_dns2,
+        data_center.guest_network_cidr,
+        data_center.domain,
+        data_center.networktype,
+        data_center.allocation_state,
+        data_center.zone_token,
+        data_center.dhcp_provider,
+        data_center.removed,
+        domain.id domain_id,
+        domain.uuid domain_uuid,
+        domain.name domain_name,
+        domain.path domain_path
+    from
+        `cloud`.`data_center`
+            left join
+        `cloud`.`domain` ON data_center.domain_id = domain.id;       
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/26be5ce2/setup/db/db/schema-40to410.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql
index d10239b..93949b8 100644
--- a/setup/db/db/schema-40to410.sql
+++ b/setup/db/db/schema-40to410.sql
@@ -1232,4 +1232,33 @@ CREATE VIEW `cloud`.`service_offering_view` AS
             left join
         `cloud`.`domain` ON disk_offering.domain_id = domain.id;
         
+DROP VIEW IF EXISTS `cloud`.`data_center_view`;
+CREATE VIEW `cloud`.`data_center_view` AS
+    select 
+        data_center.id,
+        data_center.uuid,
+        data_center.name,
+        data_center.is_security_group_enabled,
+        data_center.is_local_storage_enabled,
+        data_center.description,
+        data_center.dns1,
+        data_center.dns2,
+        data_center.internal_dns1,
+        data_center.internal_dns2,
+        data_center.guest_network_cidr,
+        data_center.domain,
+        data_center.networktype,
+        data_center.allocation_state,
+        data_center.zone_token,
+        data_center.dhcp_provider,
+        data_center.removed,
+        domain.id domain_id,
+        domain.uuid domain_uuid,
+        domain.name domain_name,
+        domain.path domain_path
+    from
+        `cloud`.`data_center`
+            left join
+        `cloud`.`domain` ON data_center.domain_id = domain.id;               
+        
 INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'direct.agent.pool.size', '500', 'Default size for DirectAgentPool');