diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 3bc7f934c04..32c2b053047 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -93,16 +93,6 @@ import com.cloud.vm.VirtualMachine.Type; 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 listDataCenters(ListZonesByCmd cmd); - /** * returns the a map of the names/values in the configuraton table * 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 5f5f9e7bda0..ccacf060b19 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 dataCenters = _mgr.listDataCenters(this); - ListResponse response = new ListResponse(); - List zoneResponses = new ArrayList(); - for (DataCenter dataCenter : dataCenters) { - ZoneResponse zoneResponse = _responseGenerator.createZoneResponse(dataCenter, showCapacities); - zoneResponse.setObjectName("zone"); - zoneResponses.add(zoneResponse); - } - response.setResponses(zoneResponses); + ListResponse response = _queryService.listDataCenters(this); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java index 72e0bb2844d..ca1cb57629c 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; } diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index add9d23943c..f3f6d3d5645 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 searchForDiskOfferings(ListDiskOfferingsCmd cmd); public ListResponse searchForServiceOfferings(ListServiceOfferingsCmd cmd); + + public ListResponse listDataCenters(ListZonesByCmd cmd); } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 9b88664fe2b..0b08b26cc32 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); + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 1965f333f35..1c8849a9e53 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()); - } - - if (showCapacities != null && showCapacities) { - List capacities = ApiDBUtils.getCapacityByClusterPodZone(dataCenter.getId(), null, null); - Set capacityResponses = new HashSet(); - 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 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); - } - // Do it for stats as well. - capacityResponses.addAll(getStatsCapacityresponse(null, null, null, dataCenter.getId())); - - zoneResponse.setCapacitites(new ArrayList(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()); - } - - zoneResponse.setType(dataCenter.getNetworkType().toString()); - zoneResponse.setAllocationState(dataCenter.getAllocationState().toString()); - zoneResponse.setZoneToken(dataCenter.getZoneToken()); - zoneResponse.setDhcpProvider(dataCenter.getDhcpProvider()); - zoneResponse.setObjectName("zone"); - return zoneResponse; + DataCenterJoinVO vOffering = ApiDBUtils.newDataCenterView(dataCenter); + return ApiDBUtils.newDataCenterResponse(vOffering, showCapacities); } - private List getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) { + public static List getDataCenterCapacityResponse(Long zoneId){ + List capacities = ApiDBUtils.getCapacityByClusterPodZone(zoneId, null, null); + Set capacityResponses = new HashSet(); + 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 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()); + } + 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)); + + return new ArrayList(capacityResponses); + } + + private static List getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) { List capacities = new ArrayList(); capacities.add(ApiDBUtils.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId)); if (clusterId == null && podId == null) { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index ad2a12f0068..ed2720082c4 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); } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index ee472961871..a943776a6c2 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; /** @@ -233,6 +244,12 @@ public class QueryManagerImpl implements QueryService, Manager { @Inject private ServiceOfferingDao _srvOfferingDao; + @Inject + private DataCenterJoinDao _dcJoinDao; + + @Inject + private DomainRouterDao _routerDao; + @Inject private HighAvailabilityManager _haMgr; @@ -2187,6 +2204,125 @@ public class QueryManagerImpl implements QueryService, Manager { + @Override + public ListResponse listDataCenters(ListZonesByCmd cmd) { + Pair, Integer> result = listDataCentersInternal(cmd); + ListResponse response = new ListResponse(); + List dcResponses = ViewResponseHelper.createDataCenterResponse(cmd.getShowCapacities(), result.first().toArray(new DataCenterJoinVO[result.first().size()])); + response.setResponses(dcResponses, result.second()); + return response; + } + + + private Pair, 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 sc = _dcJoinDao.createSearchCriteria(); + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } else { + if (keyword != null) { + SearchCriteria 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 domainIds = new ArrayList(); + 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 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 domainIds = new ArrayList(); + 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 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 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 dcIds = new HashSet(); //data centers with at least one VM running + List routers = _routerDao.listBy(account.getId()); + for (DomainRouterVO router : routers){ + dcIds.add(router.getDataCenterIdToDeployIn()); + } + if ( dcIds.size() == 0) { + return new Pair, Integer>(new ArrayList(), 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; } + + } diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index dfccdceb8d4..55d84bb5af4 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 createDataCenterResponse(Boolean showCapacities, DataCenterJoinVO... dcs) { + List respList = new ArrayList(); + for (DataCenterJoinVO vt : dcs){ + respList.add(ApiDBUtils.newDataCenterResponse(vt, showCapacities)); + } + return respList; + } } 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 00000000000..340f86f247d --- /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 { + + ZoneResponse newDataCenterResponse(DataCenterJoinVO dof, Boolean showCapacities); + + DataCenterJoinVO newDataCenterView(DataCenter dof); +} 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 00000000000..4ef182bb7ec --- /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 implements DataCenterJoinDao { + public static final Logger s_logger = Logger.getLogger(DataCenterJoinDaoImpl.class); + + + private SearchBuilder 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 sc = dofIdSearch.create(); + sc.setParameters("id", dataCenter.getId()); + List 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); + } + + +} 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 00000000000..67a3f2715f0 --- /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; + } + + +} diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 9652586124a..98da7adfa39 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 diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 8182421bf02..a2a74c25a9a 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 listDataCenters(ListZonesByCmd cmd) { - Account account = UserContext.current().getCaller(); - List 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(); - 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(); - 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 allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId()); - List allChildDomainIds = new ArrayList(); - // 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 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 routers = _routerDao.listBy(account.getId()); - for (Iterator 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 singleZone = new ArrayList(); - for (DataCenterVO zone : dcs) { - if (zone.getId() == id) { - singleZone.add(zone); - } - } - return singleZone; - } - return dcs; - } @Override public HostVO getHostBy(long hostId) { diff --git a/setup/db/create-schema-view.sql b/setup/db/create-schema-view.sql index f5c0591c0aa..f68a6cadb71 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 diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql index d10239be31d..93949b8e4fa 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');