CLOUDSTACK-681: Dedicated Resources - Explicit Dedication, Private zone, pod, cluster or host. <Patch1>

This feature allows a user to deploy VMs only in the resources dedicated to his account or domain.

1. Resources(Zones, Pods, Clusters or hosts) can be dedicated to an account or domain.
   Implemented 12 new APIs to dedicate/list/release resources:
   - dedicateZone, listDedicatedZones, releaseDedicatedZone for a Zone.
   - dedicatePod, listDedicatedPods, releaseDedicatedPod for a Pod.
   - dedicateCluster, listDedicatedClusters, releaseDedicatedCluster for a Cluster
   - dedicateHost, listDedicatedHosts, releaseDedicatedHost for a Host.
2. Once a resource(eg. pod) is dedicated to an account, other resources(eg. clusters/hosts) inside that cannot be further dedicated.
3. Once a resource is dedicated to a domain, other resources inside that can be further dedicated to its sub-domain or account.
4. If any resource (eg.cluster) is dedicated to a account/domain, then resources(eg. Pod) above that cannot be dedicated to different accounts/domain (not belonging to the same domain)
5. To use Explicit dedication, user needs to create an Affinity Group of type 'ExplicitDedication'
6. A VM can be deployed with the above affinity group parameter as an input.
7. A new ExplicitDedicationProcessor has been added which will process the affinity group of type 'Explicit Dedication' for a deployment of a VM that demands dedicated resources.
   This processor implements the AffinityGroupProcessor adapter. This processor will update the avoid list.
8. A VM requesting dedication will be deployed on dedicatd resources if available with the user account.
9. A VM requesting dedication can also be deployed on the dedicated resources available with the parent domains iff no dedicated resources are available with the current user's account or
   domain.
10. A VM (without dedication) can be deployed on shared host but not on dedicated hosts.
11. To modify the dedication, the resource has to be released first.
12. Existing Private zone functionality has been redirected to Explicit dedication of zones.
13. Updated the db upgrade schema script. A new table "dedicated_resources" has been added.
14. Added the right permissions in commands.properties
15. Unit tests:  For the new APIs and Service, added unit tests under : plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/DedicatedApiUnitTest.java
16. Marvin Test: To dedicate host, create affinity group, deploy-vm, check if vm is deployed on the dedicated host.
This commit is contained in:
Saksham Srivastava 2013-05-30 11:00:03 +05:30 committed by Prachi Damle
parent 4989f73fda
commit 17267794ad
50 changed files with 4348 additions and 41 deletions

View File

@ -0,0 +1,33 @@
// 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.dc;
import org.apache.cloudstack.acl.InfrastructureEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface DedicatedResources extends InfrastructureEntity, InternalIdentity, Identity{
long getId();
Long getDataCenterId();
Long getPodId();
Long getClusterId();
Long getHostId();
Long getDomainId();
Long getAccountId();
String getUuid();
}

View File

@ -438,6 +438,10 @@ public class EventTypes {
public static final String EVENT_PORTABLE_IP_RANGE_DELETE = "PORTABLE.IP.RANGE.DELETE";
public static final String EVENT_PORTABLE_IP_TRANSFER = "PORTABLE.IP.TRANSFER";
// Dedicated Resources
public static final String EVENT_DEDICATE_RESOURCE = "DEDICATE.RESOURCE";
public static final String EVENT_DEDICATE_RESOURCE_RELEASE = "DEDICATE.RESOURCE.RELEASE";
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking

View File

@ -29,6 +29,11 @@
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-acl-static-role-based</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-dedicated-resources</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
@ -136,6 +141,11 @@
<artifactId>cloud-plugin-planner-implicit-dedication</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-explicit-dedication</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-host-allocator-random</artifactId>

View File

@ -158,6 +158,14 @@
</map>
</property>
</bean>
<bean id="dedicatedResourceDaoImpl" class="com.cloud.dc.dao.DedicatedResourceDaoImpl">
<property name="configParams">
<map>
<entry key="cache.size" value="30" />
<entry key="cache.time.to.live" value="3600" />
</map>
</property>
</bean>
<!--
DAOs with default configuration

View File

@ -641,3 +641,16 @@ listInternalLoadBalancerVMs=1
### Network Isolation methods listing
listNetworkIsolationMethods=1
#### Dedicated Resource commands
dedicateZone=1
dedicatePod=1
dedicateCluster=1
dedicateHost=1
releaseDedicatedZone=1
releaseDedicatedPod=1
releaseDedicatedCluster=1
releaseDedicatedHost=1
listDedicatedZones=1
listDedicatedPods=1
listDedicatedClusters=1
listDedicatedHosts=1

View File

@ -45,7 +45,6 @@
<bean id="databaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker" />
<bean id="configurationDaoImpl" class="com.cloud.configuration.dao.ConfigurationDaoImpl" />
<bean id="GlobalLoadBalancingRulesServiceImpl" class ="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" />
<!--
@ -265,8 +264,17 @@
<property name="Adapters">
<list>
<ref bean="HostAntiAffinityProcessor" />
<ref bean="ExplicitDedicationProcessor"/>
</list>
</property>
</bean>
<!--
Dedicated Resources components
-->
<bean id="DedicatedResourceManagerImpl" class="org.apache.cloudstack.dedicated.manager.DedicatedResourceManagerImpl"/>
<bean id="ExplicitDedicationProcessor" class="org.apache.cloudstack.affinity.ExplicitDedicationProcessor">
<property name="name" value="ExplicitDedicationProcessor"/>
<property name="type" value="ExplicitDedication"/>
</bean>
</beans>

View File

@ -92,7 +92,6 @@ public class CloudOrchestrator implements OrchestrationService {
public VirtualMachineEntity createFromScratch(String uuid, String iso, String os, String hypervisor, String hostName, int cpu, int speed, long memory, List<String> networks, List<String> computeTags,
Map<String, String> details, String owner) {
// TODO Auto-generated method stub
return null;
}

View File

@ -34,4 +34,5 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
Map<Long, List<Long>> getPodClusterIdMap(List<Long> clusterIds);
List<Long> listDisabledClusters(long zoneId, Long podId);
List<Long> listClustersWithDisabledPods(long zoneId);
List<ClusterVO> listClustersByDcId(long zoneId);
}

View File

@ -52,6 +52,7 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
protected final SearchBuilder<ClusterVO> AvailHyperSearch;
protected final SearchBuilder<ClusterVO> ZoneSearch;
protected final SearchBuilder<ClusterVO> ZoneHyTypeSearch;
protected final SearchBuilder<ClusterVO> ZoneClusterSearch;
private static final String GET_POD_CLUSTER_MAP_PREFIX = "SELECT pod_id, id FROM cloud.cluster WHERE cluster.id IN( ";
private static final String GET_POD_CLUSTER_MAP_SUFFIX = " )";
@ -85,6 +86,10 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
AvailHyperSearch.and("zoneId", AvailHyperSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
AvailHyperSearch.select(null, Func.DISTINCT, AvailHyperSearch.entity().getHypervisorType());
AvailHyperSearch.done();
ZoneClusterSearch = createSearchBuilder();
ZoneClusterSearch.and("dataCenterId", ZoneClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
ZoneClusterSearch.done();
}
@Override
@ -223,6 +228,13 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
return customSearch(sc, null);
}
@Override
public List<ClusterVO> listClustersByDcId(long zoneId) {
SearchCriteria<ClusterVO> sc = ZoneClusterSearch.create();
sc.setParameters("dataCenterId", zoneId);
return listBy(sc);
}
@Override
public boolean remove(Long id) {
Transaction txn = Transaction.currentTxn();

View File

@ -80,4 +80,10 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
* @return
*/
List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag);
List<HostVO> findByPodId(Long podId);
List<HostVO> findByClusterId(Long clusterId);
List<HostVO> listByDataCenterId(long id);
}

View File

@ -37,6 +37,7 @@ import com.cloud.cluster.agentlb.HostTransferMapVO;
import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.ClusterDaoImpl;
import com.cloud.host.Host;
@ -86,6 +87,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected SearchBuilder<HostVO> GuidSearch;
protected SearchBuilder<HostVO> DcSearch;
protected SearchBuilder<HostVO> PodSearch;
protected SearchBuilder<HostVO> ClusterSearch;
protected SearchBuilder<HostVO> TypeSearch;
protected SearchBuilder<HostVO> StatusSearch;
protected SearchBuilder<HostVO> ResourceStateSearch;
@ -201,6 +203,9 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
DcSearch = createSearchBuilder();
DcSearch.and("dc", DcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
DcSearch.and("type", DcSearch.entity().getType(), Op.EQ);
DcSearch.and("status", DcSearch.entity().getStatus(), Op.EQ);
DcSearch.and("resourceState", DcSearch.entity().getResourceState(), Op.EQ);
DcSearch.done();
ClusterStatusSearch = createSearchBuilder();
@ -215,9 +220,13 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
TypeNameZoneSearch.done();
PodSearch = createSearchBuilder();
PodSearch.and("pod", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
PodSearch.and("podId", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
PodSearch.done();
ClusterSearch = createSearchBuilder();
ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
ClusterSearch.done();
TypeSearch = createSearchBuilder();
TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
TypeSearch.done();
@ -374,6 +383,16 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
return hosts.size();
}
@Override
public List<HostVO> listByDataCenterId(long id) {
SearchCriteria<HostVO> sc = DcSearch.create();
sc.setParameters("dcId", id);
sc.setParameters("status", Status.Up);
sc.setParameters("type", Host.Type.Routing);
sc.setParameters("resourceState", ResourceState.Enabled);
return listBy(sc);
}
@Override
public HostVO findByGuid(String guid) {
@ -906,6 +925,20 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
return findOneBy(sc);
}
@Override
public List<HostVO> findByPodId(Long podId) {
SearchCriteria<HostVO> sc = PodSearch.create();
sc.setParameters("podId", podId);
return listBy(sc);
}
@Override
public List<HostVO> findByClusterId(Long clusterId) {
SearchCriteria<HostVO> sc = ClusterSearch.create();
sc.setParameters("clusterId", clusterId);
return listBy(sc);
}
@Override
public List<HostVO> findHypervisorHostInCluster(long clusterId) {
SearchCriteria<HostVO> sc = TypeClusterStatusSearch.create();

View File

@ -0,0 +1,33 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-explicit-dedication</artifactId>
<name>Apache CloudStack Plugin - Explicit Dedication Processor</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.2.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<build>
<defaultGoal>install</defaultGoal>
<sourceDirectory>src</sourceDirectory>
</build>
</project>

View File

@ -0,0 +1,383 @@
// 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 org.apache.cloudstack.affinity;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.log4j.Logger;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.AffinityConflictException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value = AffinityGroupProcessor.class)
public class ExplicitDedicationProcessor extends AffinityProcessorBase implements AffinityGroupProcessor {
private static final Logger s_logger = Logger.getLogger(ExplicitDedicationProcessor.class);
@Inject
protected UserVmDao _vmDao;
@Inject
protected VMInstanceDao _vmInstanceDao;
@Inject
protected DataCenterDao _dcDao;
@Inject
protected DedicatedResourceDao _dedicatedDao;
@Inject
protected HostPodDao _podDao;
@Inject
protected ClusterDao _clusterDao;
@Inject
protected HostDao _hostDao;
@Inject
protected DomainDao _domainDao;
@Inject
protected AffinityGroupDao _affinityGroupDao;
@Inject
protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
/**
* This method will process the affinity group of type 'Explicit Dedication' for a deployment of a VM that demands dedicated resources.
* For ExplicitDedicationProcessor we need to add dedicated resources into the IncludeList based on the level we have dedicated resources available.
* For eg. if admin dedicates a pod to a domain, then all the user in that domain can use the resources of that pod.
* We need to take care of the situation when dedicated resources further have resources dedicated to sub-domain/account.
* This IncludeList is then used to update the avoid list for a given data center.
*/
@Override
public void process(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan,
ExcludeList avoid) throws AffinityConflictException {
VirtualMachine vm = vmProfile.getVirtualMachine();
List<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), getType());
DataCenter dc = _dcDao.findById(vm.getDataCenterId());
long domainId = vm.getDomainId();
long accountId = vm.getAccountId();
for (AffinityGroupVMMapVO vmGroupMapping : vmGroupMappings) {
if (vmGroupMapping != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Processing affinity group of type 'ExplicitDedication' for VM Id: " + vm.getId());
}
List<DedicatedResourceVO> dr = _dedicatedDao.listByAccountId(accountId);
List<DedicatedResourceVO> drOfDomain = searchInDomainResources(domainId);
List<DedicatedResourceVO> drOfParentDomain = searchInParentDomainResources(domainId);
List<DedicatedResourceVO> resourceList = new ArrayList<DedicatedResourceVO>();
resourceList.addAll(dr);
resourceList.addAll(drOfDomain);
resourceList.addAll(drOfParentDomain);
boolean canUse = false;
if (plan.getHostId() != null) {
HostVO host = _hostDao.findById(plan.getHostId());
ClusterVO clusterofHost = _clusterDao.findById(host.getClusterId());
HostPodVO podOfHost = _podDao.findById(host.getPodId());
DataCenterVO zoneOfHost = _dcDao.findById(host.getDataCenterId());
if (resourceList != null && resourceList.size() != 0) {
for(DedicatedResourceVO resource : resourceList){
if ((resource.getHostId() != null && resource.getHostId() == plan.getHostId()) ||
(resource.getClusterId() != null && resource.getClusterId() == clusterofHost.getId()) ||
(resource.getPodId() != null && resource.getPodId() == podOfHost.getId()) ||
(resource.getDataCenterId() != null && resource.getDataCenterId() == zoneOfHost.getId())){
canUse = true;
}
}
}
if (!canUse) {
throw new CloudRuntimeException("Cannot use this host " + host.getName() + " for explicit dedication");
}
} else if (plan.getClusterId() != null) {
ClusterVO cluster = _clusterDao.findById(plan.getClusterId());
HostPodVO podOfCluster = _podDao.findById(cluster.getPodId());
DataCenterVO zoneOfCluster = _dcDao.findById(cluster.getDataCenterId());
List<HostVO> hostToUse = new ArrayList<HostVO>();
// check whether this cluster or its pod is dedicated
if (resourceList != null && resourceList.size() != 0) {
for(DedicatedResourceVO resource : resourceList){
if ((resource.getClusterId() != null && resource.getClusterId() == cluster.getId()) ||
(resource.getPodId() != null && resource.getPodId() == podOfCluster.getId()) ||
(resource.getDataCenterId() != null && resource.getDataCenterId() == zoneOfCluster.getId())){
canUse = true;
}
// check for all dedicated host; if it belongs to this cluster
if (!canUse){
if (resource.getHostId() != null) {
HostVO dHost = _hostDao.findById(resource.getHostId());
if (dHost.getClusterId() == cluster.getId()) {
hostToUse.add(dHost);
}
}
}
}
}
if (hostToUse.isEmpty() && !canUse) {
throw new CloudRuntimeException("Cannot use this cluster " + cluster.getName() + " for explicit dedication");
}
if (hostToUse != null && hostToUse.size() != 0) {
// add other non-dedicated hosts to avoid list
List<HostVO> hostList = _hostDao.findByClusterId(cluster.getId());
for (HostVO host : hostList){
if (!hostToUse.contains(host)) {
avoid.addHost(host.getId());
}
}
}
} else if (plan.getPodId() != null) {
HostPodVO pod = _podDao.findById(plan.getPodId());
DataCenterVO zoneOfPod = _dcDao.findById(pod.getDataCenterId());
List<ClusterVO> clustersToUse = new ArrayList<ClusterVO>();
List<HostVO> hostsToUse = new ArrayList<HostVO>();
// check whether this cluster or its pod is dedicated
if (resourceList != null && resourceList.size() != 0) {
for(DedicatedResourceVO resource : resourceList){
if ((resource.getPodId() != null && resource.getPodId() == pod.getId()) ||
(resource.getDataCenterId() != null && resource.getDataCenterId() == zoneOfPod.getId())){
canUse = true;
}
// check for all dedicated cluster/host; if it belongs to this pod
if (!canUse){
if (resource.getClusterId() != null) {
ClusterVO dCluster = _clusterDao.findById(resource.getClusterId());
if (dCluster.getPodId() == pod.getId()) {
clustersToUse.add(dCluster);
}
}
if (resource.getHostId() != null) {
HostVO dHost = _hostDao.findById(resource.getHostId());
if (dHost.getPodId() == pod.getId()) {
hostsToUse.add(dHost);
}
}
}
}
}
if (hostsToUse.isEmpty() && clustersToUse.isEmpty() && !canUse) {
throw new CloudRuntimeException("Cannot use this pod " + pod.getName() + " for explicit dedication");
}
if (clustersToUse != null && clustersToUse.size() != 0) {
// add other non-dedicated clusters to avoid list
List<ClusterVO> clusterList = _clusterDao.listByPodId(pod.getId());
for (ClusterVO cluster : clusterList){
if (!clustersToUse.contains(cluster)) {
avoid.addCluster(cluster.getId());
}
}
}
if (hostsToUse != null && hostsToUse.size() != 0) {
// add other non-dedicated hosts to avoid list
List<HostVO> hostList = _hostDao.findByPodId(pod.getId());
for (HostVO host : hostList){
if (!hostsToUse.contains(host)) {
avoid.addHost(host.getId());
}
}
}
} else {
//check all resources under this zone
if (dr != null && dr.size() != 0) {
avoid = updateAvoidList(dr, avoid, dc);
} else if(drOfDomain != null && drOfDomain.size() != 0){
avoid = updateAvoidList(drOfDomain, avoid, dc);
} else if(drOfParentDomain != null && drOfParentDomain.size() != 0){
avoid = updateAvoidList(drOfParentDomain, avoid, dc);
} else {
avoid.addDataCenter(dc.getId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("No dedicated resources available for this domain or account");
}
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("ExplicitDedicationProcessor returns Avoid List as: Deploy avoids pods: " + avoid.getPodsToAvoid() + ", clusters: "
+ avoid.getClustersToAvoid() + ", hosts: " + avoid.getHostsToAvoid());
}
}
}
}
}
private ExcludeList updateAvoidList(List<DedicatedResourceVO> dedicatedResources, ExcludeList avoidList, DataCenter dc) {
ExcludeList includeList = new ExcludeList();
for (DedicatedResourceVO dr : dedicatedResources) {
if (dr.getHostId() != null){
includeList.addHost(dr.getHostId());
HostVO dedicatedHost = _hostDao.findById(dr.getHostId());
includeList.addCluster(dedicatedHost.getClusterId());
includeList.addPod(dedicatedHost.getPodId());
}
if (dr.getClusterId() != null) {
includeList.addCluster(dr.getClusterId());
//add all hosts inside this in includeList
List<HostVO> hostList = _hostDao.findByClusterId(dr.getClusterId());
for (HostVO host : hostList) {
DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
if (dHost != null) {
avoidList.addHost(host.getId());
} else {
includeList.addHost(host.getId());
}
}
ClusterVO dedicatedCluster = _clusterDao.findById(dr.getClusterId());
includeList.addPod(dedicatedCluster.getPodId());
}
if (dr.getPodId() != null) {
includeList.addPod(dr.getPodId());
//add all cluster under this pod in includeList
List<ClusterVO> clusterList = _clusterDao.listByPodId(dr.getPodId());
for (ClusterVO cluster : clusterList) {
if (_dedicatedDao.findByClusterId(cluster.getId()) != null) {
avoidList.addCluster(cluster.getId());
} else {
includeList.addCluster(cluster.getId());
}
}
//add all hosts inside this pod in includeList
List<HostVO> hostList = _hostDao.findByPodId(dr.getPodId());
for (HostVO host : hostList) {
if (_dedicatedDao.findByHostId(host.getId()) != null) {
avoidList.addHost(host.getId());
} else {
includeList.addHost(host.getId());
}
}
}
if (dr.getDataCenterId() != null) {
includeList.addDataCenter(dr.getDataCenterId());
//add all Pod under this data center in includeList
List<HostPodVO> podList = _podDao.listByDataCenterId(dr.getDataCenterId());
for (HostPodVO pod : podList) {
if (_dedicatedDao.findByPodId(pod.getId()) != null) {
avoidList.addPod(pod.getId());
} else {
includeList.addPod(pod.getId());
}
}
List<ClusterVO> clusterList = _clusterDao.listClustersByDcId(dr.getDataCenterId());
for (ClusterVO cluster : clusterList) {
if (_dedicatedDao.findByClusterId(cluster.getId()) != null) {
avoidList.addCluster(cluster.getId());
} else {
includeList.addCluster(cluster.getId());
}
}
//add all hosts inside this in includeList
List<HostVO> hostList = _hostDao.listByDataCenterId(dr.getDataCenterId());
for (HostVO host : hostList) {
if (_dedicatedDao.findByHostId(host.getId()) != null) {
avoidList.addHost(host.getId());
} else {
includeList.addHost(host.getId());
}
}
}
}
//Update avoid list using includeList.
//add resources in avoid list which are not in include list.
List<HostPodVO> pods = _podDao.listByDataCenterId(dc.getId());
List<ClusterVO> clusters = _clusterDao.listClustersByDcId(dc.getId());
List<HostVO> hosts = _hostDao.listByDataCenterId(dc.getId());
Set<Long> podsInIncludeList = includeList.getPodsToAvoid();
Set<Long> clustersInIncludeList = includeList.getClustersToAvoid();
Set<Long> hostsInIncludeList = includeList.getHostsToAvoid();
for (HostPodVO pod : pods){
if (podsInIncludeList != null && !podsInIncludeList.contains(pod.getId())) {
avoidList.addPod(pod.getId());
}
}
for (ClusterVO cluster : clusters) {
if (clustersInIncludeList != null && !clustersInIncludeList.contains(cluster.getId())) {
avoidList.addCluster(cluster.getId());
}
}
for (HostVO host : hosts) {
if (hostsInIncludeList != null && !hostsInIncludeList.contains(host.getId())) {
avoidList.addHost(host.getId());
}
}
return avoidList;
}
private List<DedicatedResourceVO> searchInParentDomainResources(long domainId) {
List<Long> domainIds = getDomainParentIds(domainId);
List<DedicatedResourceVO> dr = new ArrayList<DedicatedResourceVO>();
for (Long id : domainIds) {
List<DedicatedResourceVO> resource = _dedicatedDao.listByDomainId(id);
if(resource != null) {
dr.addAll(resource);
}
}
return dr;
}
private List<DedicatedResourceVO> searchInDomainResources(long domainId) {
List<DedicatedResourceVO> dr = _dedicatedDao.listByDomainId(domainId);
return dr;
}
private List<Long> getDomainParentIds(long domainId) {
DomainVO domainRecord = _domainDao.findById(domainId);
List<Long> domainIds = new ArrayList<Long>();
domainIds.add(domainRecord.getId());
while (domainRecord.getParent() != null ){
domainRecord = _domainDao.findById(domainRecord.getParent());
domainIds.add(domainRecord.getId());
}
return domainIds;
}
}

View File

@ -0,0 +1,29 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-dedicated-resources</artifactId>
<name>Apache CloudStack Plugin - Dedicated Resources</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
</project>

View File

@ -0,0 +1,115 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateClusterResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResources;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "dedicateCluster", description= "Dedicate an existing cluster", responseObject = DedicateClusterResponse.class )
public class DedicateClusterCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DedicateClusterCmd.class.getName());
private static final String s_name = "dedicateclusterresponse";
@Inject DedicatedService dedicatedService;
@Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class,
required=true, description="the ID of the Cluster")
private Long clusterId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getClusterId() {
return clusterId;
}
public Long getDomainId() {
return domainId;
}
public String getAccountName() {
return accountName;
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE;
}
@Override
public String getEventDescription() {
return "dedicating a cluster";
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
List<? extends DedicatedResources> result = dedicatedService.dedicateCluster(getClusterId(), getDomainId(), getAccountName());
ListResponse<DedicateClusterResponse> response = new ListResponse<DedicateClusterResponse>();
List<DedicateClusterResponse> clusterResponseList = new ArrayList<DedicateClusterResponse>();
if (result != null) {
for (DedicatedResources resource : result) {
DedicateClusterResponse clusterResponse = dedicatedService.createDedicateClusterResponse(resource);
clusterResponseList.add(clusterResponse);
}
response.setResponses(clusterResponseList);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate cluster");
}
}
}

View File

@ -0,0 +1,118 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateHostResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResources;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "dedicateHost", description = "Dedicates a host.", responseObject = DedicateHostResponse.class)
public class DedicateHostCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DedicateHostCmd.class.getName());
private static final String s_name = "dedicatehostresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType = HostResponse.class,
required=true, description="the ID of the host to update")
private Long hostId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getHostId() {
return hostId;
}
public Long getDomainId() {
return domainId;
}
public String getAccountName() {
return accountName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
List<? extends DedicatedResources> result = dedicatedService.dedicateHost(getHostId(), getDomainId(), getAccountName());
ListResponse<DedicateHostResponse> response = new ListResponse<DedicateHostResponse>();
List<DedicateHostResponse> hostResponseList = new ArrayList<DedicateHostResponse>();
if (result != null) {
for (DedicatedResources resource : result) {
DedicateHostResponse hostResponse = dedicatedService.createDedicateHostResponse(resource);
hostResponseList.add(hostResponse);
}
response.setResponses(hostResponseList);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate host");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE;
}
@Override
public String getEventDescription() {
return "dedicating a host";
}
}

View File

@ -0,0 +1,120 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.dedicated.api.response.DedicatePodResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResources;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "dedicatePod", description ="Dedicates a Pod.", responseObject = DedicatePodResponse.class)
public class DedicatePodCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DedicatePodCmd.class.getName());
private static final String s_name = "dedicatepodresponse";
@Inject public DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
required=true, description="the ID of the Pod")
private Long podId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getPodId() {
return podId;
}
public Long getDomainId() {
return domainId;
}
public String getAccountName() {
return accountName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
List<? extends DedicatedResources> result = dedicatedService.dedicatePod(getPodId(), getDomainId(), getAccountName());
ListResponse<DedicatePodResponse> response = new ListResponse<DedicatePodResponse>();
List<DedicatePodResponse> podResponseList = new ArrayList<DedicatePodResponse>();
if (result != null) {
for (DedicatedResources resource : result) {
DedicatePodResponse podresponse = dedicatedService.createDedicatePodResponse(resource);
podResponseList.add(podresponse);
}
response.setResponses(podResponseList);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate pod");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE;
}
@Override
public String getEventDescription() {
return "dedicating a pod";
}
}

View File

@ -0,0 +1,120 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateZoneResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResources;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "dedicateZone", description ="Dedicates a zones.", responseObject = DedicateZoneResponse.class)
public class DedicateZoneCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DedicateZoneCmd.class.getName());
private static final String s_name = "dedicatezoneresponse";
@Inject public DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
required=true, description="the ID of the zone")
private Long zoneId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getZoneId() {
return zoneId;
}
public Long getDomainId() {
return domainId;
}
public String getAccountName() {
return accountName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
List<? extends DedicatedResources> result = dedicatedService.dedicateZone(getZoneId(), getDomainId(), getAccountName());
ListResponse<DedicateZoneResponse> response = new ListResponse<DedicateZoneResponse>();
List<DedicateZoneResponse> zoneResponseList = new ArrayList<DedicateZoneResponse>();
if (result != null) {
for (DedicatedResources resource : result) {
DedicateZoneResponse zoneresponse = dedicatedService.createDedicateZoneResponse(resource);
zoneResponseList.add(zoneresponse);
}
response.setResponses(zoneResponseList);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate zone");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE;
}
@Override
public String getEventDescription() {
return "dedicating a zone";
}
}

View File

@ -0,0 +1,105 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateClusterResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.DedicatedResources;
import com.cloud.utils.Pair;
@APICommand(name = "listDedicatedClusters", description = "Lists dedicated clusters.", responseObject = DedicateClusterResponse.class)
public class ListDedicatedClustersCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListDedicatedClustersCmd.class.getName());
private static final String s_name = "listdedicatedclustersresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class,
description="the ID of the cluster")
private Long clusterId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
description="the ID of the domain associated with the cluster")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
description = "the name of the account associated with the cluster. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getClusterId() {
return clusterId;
}
public Long getDomainId(){
return domainId;
}
public String getAccountName(){
return accountName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public void execute(){
Pair<List<? extends DedicatedResourceVO>, Integer> result = dedicatedService.listDedicatedClusters(this);
ListResponse<DedicateClusterResponse> response = new ListResponse<DedicateClusterResponse>();
List<DedicateClusterResponse> Responses = new ArrayList<DedicateClusterResponse>();
if (result != null) {
for (DedicatedResources resource : result.first()) {
DedicateClusterResponse clusterResponse = dedicatedService.createDedicateClusterResponse(resource);
Responses.add(clusterResponse);
}
response.setResponses(Responses, result.second());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated clusters");
}
}
}

View File

@ -0,0 +1,105 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateHostResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.DedicatedResources;
import com.cloud.utils.Pair;
@APICommand(name = "listDedicatedHosts", description = "Lists dedicated hosts.", responseObject = DedicateHostResponse.class)
public class ListDedicatedHostsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListDedicatedHostsCmd.class.getName());
private static final String s_name = "listdedicatedhostsresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
description="the ID of the host")
private Long hostId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
description="the ID of the domain associated with the host")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
description = "the name of the account associated with the host. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getHostId() {
return hostId;
}
public Long getDomainId(){
return domainId;
}
public String getAccountName(){
return accountName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////l
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public void execute(){
Pair<List<? extends DedicatedResourceVO>, Integer> result = dedicatedService.listDedicatedHosts(this);
ListResponse<DedicateHostResponse> response = new ListResponse<DedicateHostResponse>();
List<DedicateHostResponse> Responses = new ArrayList<DedicateHostResponse>();
if (result != null) {
for (DedicatedResources resource : result.first()) {
DedicateHostResponse hostResponse = dedicatedService.createDedicateHostResponse(resource);
Responses.add(hostResponse);
}
response.setResponses(Responses, result.second());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated hosts");
}
}
}

View File

@ -0,0 +1,105 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.dedicated.api.response.DedicatePodResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.DedicatedResources;
import com.cloud.utils.Pair;
@APICommand(name = "listDedicatedPods", description = "Lists dedicated pods.", responseObject = DedicatePodResponse.class)
public class ListDedicatedPodsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListDedicatedPodsCmd.class.getName());
private static final String s_name = "listdedicatedpodsresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
description="the ID of the pod")
private Long podId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
description="the ID of the domain associated with the pod")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
description = "the name of the account associated with the pod. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getPodId() {
return podId;
}
public Long getDomainId(){
return domainId;
}
public String getAccountName(){
return accountName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public void execute(){
Pair<List<? extends DedicatedResourceVO>, Integer> result = dedicatedService.listDedicatedPods(this);
ListResponse<DedicatePodResponse> response = new ListResponse<DedicatePodResponse>();
List<DedicatePodResponse> Responses = new ArrayList<DedicatePodResponse>();
if (result != null) {
for (DedicatedResources resource : result.first()) {
DedicatePodResponse podresponse = dedicatedService.createDedicatePodResponse(resource);
Responses.add(podresponse);
}
response.setResponses(Responses, result.second());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated pods");
}
}
}

View File

@ -0,0 +1,105 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateZoneResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.DedicatedResources;
import com.cloud.utils.Pair;
@APICommand(name = "listDedicatedZones", description = "List dedicated zones.", responseObject = DedicateZoneResponse.class)
public class ListDedicatedZonesCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListDedicatedZonesCmd.class.getName());
private static final String s_name = "listdedicatedzonesresponse";
@Inject DedicatedService _dedicatedservice;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
description="the ID of the Zone")
private Long zoneId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
description="the ID of the domain associated with the zone")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
description = "the name of the account associated with the zone. Must be used with domainId.")
private String accountName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getZoneId() {
return zoneId;
}
public Long getDomainId(){
return domainId;
}
public String getAccountName(){
return accountName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public void execute(){
Pair<List<? extends DedicatedResourceVO>, Integer> result = _dedicatedservice.listDedicatedZones(this);
ListResponse<DedicateZoneResponse> response = new ListResponse<DedicateZoneResponse>();
List<DedicateZoneResponse> Responses = new ArrayList<DedicateZoneResponse>();
if (result != null) {
for (DedicatedResources resource : result.first()) {
DedicateZoneResponse zoneResponse = _dedicatedservice.createDedicateZoneResponse(resource);
Responses.add(zoneResponse);
}
response.setResponses(Responses, result.second());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated zones");
}
}
}

View File

@ -0,0 +1,91 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "releaseDedicatedCluster", description = "Release the dedication for cluster", responseObject = SuccessResponse.class)
public class ReleaseDedicatedClusterCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedClusterCmd.class.getName());
private static final String s_name = "releasededicatedclusterresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class,
required=true, description="the ID of the Cluster")
private Long clusterId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getClusterId() {
return clusterId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
boolean result = dedicatedService.releaseDedicatedResource(null, null, getClusterId(), null);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated cluster");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
}
@Override
public String getEventDescription() {
return "releasing dedicated cluster";
}
}

View File

@ -0,0 +1,91 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "releaseDedicatedHost", description = "Release the dedication for host", responseObject = SuccessResponse.class)
public class ReleaseDedicatedHostCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedHostCmd.class.getName());
private static final String s_name = "releasededicatedhostresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
required=true, description="the ID of the host")
private Long hostId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getHostId() {
return hostId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
boolean result = dedicatedService.releaseDedicatedResource(null, null, null, getHostId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated Host");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
}
@Override
public String getEventDescription() {
return "releasing dedicated host";
}
}

View File

@ -0,0 +1,91 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "releaseDedicatedPod", description = "Release the dedication for the pod", responseObject = SuccessResponse.class)
public class ReleaseDedicatedPodCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedPodCmd.class.getName());
private static final String s_name = "releasededicatedpodresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
required=true, description="the ID of the Pod")
private Long podId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getPodId() {
return podId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
boolean result = dedicatedService.releaseDedicatedResource(null, getPodId(), null, null);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated pod");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
}
@Override
public String getEventDescription() {
return "releasing dedicated pod";
}
}

View File

@ -0,0 +1,91 @@
// 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 org.apache.cloudstack.dedicated.api.commands;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@APICommand(name = "releaseDedicatedZone", description = "Release dedication of zone", responseObject = SuccessResponse.class)
public class ReleaseDedicatedZoneCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedZoneCmd.class.getName());
private static final String s_name = "releasededicatedzoneresponse";
@Inject DedicatedService dedicatedService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType= ZoneResponse.class,
required=true, description="the ID of the Zone")
private Long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getZoneId() {
return zoneId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
boolean result = dedicatedService.releaseDedicatedResource(getZoneId(), null, null, null);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated zone");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
}
@Override
public String getEventDescription() {
return "releasing dedicated zone";
}
}

View File

@ -0,0 +1,79 @@
// 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 org.apache.cloudstack.dedicated.api.response;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class DedicateClusterResponse extends BaseResponse {
@SerializedName("id") @Param(description="the ID of the dedicated resource")
private String id;
@SerializedName("clusterid") @Param(description="the ID of the cluster")
private String clusterId;
@SerializedName("clustername") @Param(description="the name of the cluster")
private String clusterName;
@SerializedName("domainid") @Param(description="the domain ID of the cluster")
private String domainId;
@SerializedName("accountid") @Param(description="the Account ID of the cluster")
private String accountId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClusterId() {
return clusterId;
}
public void setClusterId(String clusterId) {
this.clusterId = clusterId;
}
public String getClusterName() {
return clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public String getDomainId() {
return domainId;
}
public void setDomainId(String domainId) {
this.domainId = domainId;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
}

View File

@ -0,0 +1,79 @@
// 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 org.apache.cloudstack.dedicated.api.response;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class DedicateHostResponse extends BaseResponse {
@SerializedName("id") @Param(description="the ID of the dedicated resource")
private String id;
@SerializedName("hostid") @Param(description="the ID of the host")
private String hostId;
@SerializedName("hostname") @Param(description="the name of the host")
private String hostName;
@SerializedName("domainid") @Param(description="the domain ID of the host")
private String domainId;
@SerializedName("accountid") @Param(description="the Account ID of the host")
private String accountId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getHostId() {
return hostId;
}
public void setHostId(String hostId) {
this.hostId = hostId;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public String getDomainId() {
return domainId;
}
public void setDomainId(String domainId) {
this.domainId = domainId;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
}

View File

@ -0,0 +1,82 @@
// 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 org.apache.cloudstack.dedicated.api.response;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.dc.DedicatedResources;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
@EntityReference(value = DedicatedResources.class)
public class DedicatePodResponse extends BaseResponse {
@SerializedName("id") @Param(description="the ID of the dedicated resource")
private String id;
@SerializedName("podid") @Param(description="the ID of the Pod")
private String podId;
@SerializedName("podname") @Param(description="the Name of the Pod")
private String podName;
@SerializedName("domainid") @Param(description="the domain ID to which the Pod is dedicated")
private String domainId;
@SerializedName("accountid") @Param(description="the Account Id to which the Pod is dedicated")
private String accountId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPodId() {
return podId;
}
public void setPodId(String podId) {
this.podId = podId;
}
public String getPodName() {
return podName;
}
public void setPodName(String podName) {
this.podName = podName;
}
public String getDomainId() {
return domainId;
}
public void setDomainId(String domainId) {
this.domainId = domainId;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
}

View File

@ -0,0 +1,83 @@
// 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 org.apache.cloudstack.dedicated.api.response;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.dc.DedicatedResources;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
@EntityReference(value = DedicatedResources.class)
public class DedicateZoneResponse extends BaseResponse {
@SerializedName("id") @Param(description="the ID of the dedicated resource")
private String id;
@SerializedName("zoneid") @Param(description="the ID of the Zone")
private String zoneId;
@SerializedName("zonename") @Param(description="the Name of the Zone")
private String zoneName;
@SerializedName("domainid") @Param(description="the domain ID to which the Zone is dedicated")
private String domainId;
@SerializedName("accountid") @Param(description="the Account Id to which the Zone is dedicated")
private String accountId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getZoneId() {
return zoneId;
}
public void setZoneId(String zoneId) {
this.zoneId = zoneId;
}
public String getZoneName() {
return zoneName;
}
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public String getDomainId() {
return domainId;
}
public void setDomainId(String domainId) {
this.domainId = domainId;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
}

View File

@ -0,0 +1,816 @@
// 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 org.apache.cloudstack.dedicated.manager;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.dedicated.api.commands.DedicateClusterCmd;
import org.apache.cloudstack.dedicated.api.commands.DedicateHostCmd;
import org.apache.cloudstack.dedicated.api.commands.DedicatePodCmd;
import org.apache.cloudstack.dedicated.api.commands.DedicateZoneCmd;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedClustersCmd;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedHostsCmd;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedPodsCmd;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedZonesCmd;
import org.apache.cloudstack.dedicated.api.commands.ReleaseDedicatedClusterCmd;
import org.apache.cloudstack.dedicated.api.commands.ReleaseDedicatedHostCmd;
import org.apache.cloudstack.dedicated.api.commands.ReleaseDedicatedPodCmd;
import org.apache.cloudstack.dedicated.api.commands.ReleaseDedicatedZoneCmd;
import org.apache.cloudstack.dedicated.api.response.DedicateClusterResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateHostResponse;
import org.apache.cloudstack.dedicated.api.response.DedicatePodResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateZoneResponse;
import org.apache.cloudstack.dedicated.services.DedicatedService;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.DedicatedResources;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Pod;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserContext;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.UserVmDao;
@Component
@Local({DedicatedService.class })
public class DedicatedResourceManagerImpl implements DedicatedService {
private static final Logger s_logger = Logger.getLogger(DedicatedResourceManagerImpl.class);
@Inject AccountDao _accountDao;
@Inject DomainDao _domainDao;
@Inject HostPodDao _podDao;
@Inject ClusterDao _clusterDao;
@Inject HostDao _hostDao;
@Inject DedicatedResourceDao _dedicatedDao;
@Inject DataCenterDao _zoneDao;
@Inject AccountManager _accountMgr;
@Inject UserVmDao _userVmDao;
@Inject ConfigurationDao _configDao;
private int capacityReleaseInterval;
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
return true;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Zone")
public List<DedicatedResourceVO> dedicateZone(Long zoneId, Long domainId, String accountName) {
Long accountId = null;
List<HostVO> hosts = null;
if(accountName != null){
Account caller = UserContext.current().getCaller();
Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
accountId = owner.getId();
}
List<Long> childDomainIds = getDomainChildIds(domainId);
childDomainIds.add(domainId);
checkAccountAndDomain(accountId, domainId);
DataCenterVO dc = _zoneDao.findById(zoneId);
if (dc == null) {
throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
} else {
DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zoneId);
//check if zone is dedicated
if(dedicatedZone != null) {
s_logger.error("Zone " + dc.getName() + " is already dedicated");
throw new CloudRuntimeException("Zone " + dc.getName() + " is already dedicated");
}
//check if any resource under this zone is dedicated to different account or sub-domain
List<HostPodVO> pods = _podDao.listByDataCenterId(dc.getId());
List<DedicatedResourceVO> podsToRelease = new ArrayList<DedicatedResourceVO>();
List<DedicatedResourceVO> clustersToRelease = new ArrayList<DedicatedResourceVO>();
List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
for (HostPodVO pod : pods) {
DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId());
if (dPod != null) {
if(!(childDomainIds.contains(dPod.getDomainId()))) {
throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
if (accountId != null) {
if (dPod.getAccountId() == accountId) {
podsToRelease.add(dPod);
} else {
s_logger.error("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
} else {
if (dPod.getAccountId() == null && dPod.getDomainId() == domainId) {
podsToRelease.add(dPod);
}
}
}
}
for (DedicatedResourceVO dr : podsToRelease) {
releaseDedicatedResource(null, dr.getPodId(), null, null);
}
List<ClusterVO> clusters = _clusterDao.listClustersByDcId(dc.getId());
for (ClusterVO cluster : clusters) {
DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
if (dCluster != null) {
if(!(childDomainIds.contains(dCluster.getDomainId()))) {
throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
if (accountId != null) {
if (dCluster.getAccountId() == accountId) {
clustersToRelease.add(dCluster);
} else {
s_logger.error("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
} else {
if (dCluster.getAccountId() == null && dCluster.getDomainId() == domainId) {
clustersToRelease.add(dCluster);
}
}
}
}
for (DedicatedResourceVO dr : clustersToRelease) {
releaseDedicatedResource(null, null, dr.getClusterId(), null);
}
hosts = _hostDao.listByDataCenterId(dc.getId());
for (HostVO host : hosts) {
DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
if (dHost != null) {
if(!(childDomainIds.contains(dHost.getDomainId()))) {
throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
if (accountId != null) {
if (dHost.getAccountId() == accountId) {
hostsToRelease.add(dHost);
} else {
s_logger.error("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
} else {
if (dHost.getAccountId() == null && dHost.getDomainId() == domainId) {
hostsToRelease.add(dHost);
}
}
}
}
for (DedicatedResourceVO dr : hostsToRelease) {
releaseDedicatedResource(null, null, null, dr.getHostId());
}
}
checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null);
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
dedicatedResource.setAccountId(accountId);
}
dedicatedResource = _dedicatedDao.persist(dedicatedResource);
} catch (Exception e) {
s_logger.error("Unable to dedicate zone due to " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
}
txn.commit();
List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
result.add(dedicatedResource);
return result;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Pod")
public List<DedicatedResourceVO> dedicatePod(Long podId, Long domainId, String accountName) {
Long accountId = null;
if(accountName != null){
Account caller = UserContext.current().getCaller();
Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
accountId = owner.getId();
}
List<Long> childDomainIds = getDomainChildIds(domainId);
childDomainIds.add(domainId);
checkAccountAndDomain(accountId, domainId);
HostPodVO pod = _podDao.findById(podId);
List<HostVO> hosts = null;
if (pod == null) {
throw new InvalidParameterValueException("Unable to find pod by id " + podId);
} else {
DedicatedResourceVO dedicatedPod = _dedicatedDao.findByPodId(podId);
DedicatedResourceVO dedicatedZoneOfPod = _dedicatedDao.findByZoneId(pod.getDataCenterId());
//check if pod is dedicated
if(dedicatedPod != null ) {
s_logger.error("Pod " + pod.getName() + " is already dedicated");
throw new CloudRuntimeException("Pod " + pod.getName() + " is already dedicated");
}
if (dedicatedZoneOfPod != null) {
boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfPod.getDomainId()).contains(domainId);
//can dedicate a pod to an account/domain if zone is dedicated to parent-domain
if (dedicatedZoneOfPod.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
|| (accountId != null && !(dedicatedZoneOfPod.getDomainId() == domainId || domainIdInChildreanList))) {
DataCenterVO zone = _zoneDao.findById(pod.getDataCenterId());
s_logger.error("Cannot dedicate Pod. Its zone is already dedicated");
throw new CloudRuntimeException("Pod's Zone " + zone.getName() + " is already dedicated");
}
}
//check if any resource under this pod is dedicated to different account or sub-domain
List<ClusterVO> clusters = _clusterDao.listByPodId(pod.getId());
List<DedicatedResourceVO> clustersToRelease = new ArrayList<DedicatedResourceVO>();
List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
for (ClusterVO cluster : clusters) {
DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
if (dCluster != null) {
if(!(childDomainIds.contains(dCluster.getDomainId()))) {
throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
}
/*if all dedicated resources belongs to same account and domain then we should release dedication
and make new entry for this Pod*/
if (accountId != null) {
if (dCluster.getAccountId() == accountId) {
clustersToRelease.add(dCluster);
} else {
s_logger.error("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
}
} else {
if (dCluster.getAccountId() == null && dCluster.getDomainId() == domainId) {
clustersToRelease.add(dCluster);
}
}
}
}
for (DedicatedResourceVO dr : clustersToRelease) {
releaseDedicatedResource(null, null, dr.getClusterId(), null);
}
hosts = _hostDao.findByPodId(pod.getId());
for (HostVO host : hosts) {
DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
if (dHost != null) {
if(!(getDomainChildIds(domainId).contains(dHost.getDomainId()))) {
throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
}
if (accountId != null) {
if (dHost.getAccountId() == accountId) {
hostsToRelease.add(dHost);
} else {
s_logger.error("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
}
} else {
if (dHost.getAccountId() == null && dHost.getDomainId() == domainId) {
hostsToRelease.add(dHost);
}
}
}
}
for (DedicatedResourceVO dr : hostsToRelease) {
releaseDedicatedResource(null, null, null, dr.getHostId());
}
}
checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null);
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
dedicatedResource.setAccountId(accountId);
}
dedicatedResource = _dedicatedDao.persist(dedicatedResource);
} catch (Exception e) {
s_logger.error("Unable to dedicate pod due to " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to dedicate pod. Please contact Cloud Support.");
}
txn.commit();
List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
result.add(dedicatedResource);
return result;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Cluster")
public List<DedicatedResourceVO> dedicateCluster(Long clusterId, Long domainId, String accountName) {
Long accountId = null;
List<HostVO> hosts = null;
if(accountName != null){
Account caller = UserContext.current().getCaller();
Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
accountId = owner.getId();
}
List<Long> childDomainIds = getDomainChildIds(domainId);
childDomainIds.add(domainId);
checkAccountAndDomain(accountId, domainId);
ClusterVO cluster = _clusterDao.findById(clusterId);
if (cluster == null) {
throw new InvalidParameterValueException("Unable to find cluster by id " + clusterId);
} else {
DedicatedResourceVO dedicatedCluster = _dedicatedDao.findByClusterId(clusterId);
DedicatedResourceVO dedicatedPodOfCluster = _dedicatedDao.findByPodId(cluster.getPodId());
DedicatedResourceVO dedicatedZoneOfCluster = _dedicatedDao.findByZoneId(cluster.getDataCenterId());
//check if cluster is dedicated
if(dedicatedCluster != null) {
s_logger.error("Cluster " + cluster.getName() + " is already dedicated");
throw new CloudRuntimeException("Cluster "+ cluster.getName() + " is already dedicated");
}
if (dedicatedPodOfCluster != null) {
boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfCluster.getDomainId()).contains(domainId);
//can dedicate a cluster to an account/domain if pod is dedicated to parent-domain
if (dedicatedPodOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
|| (accountId != null && !(dedicatedPodOfCluster.getDomainId() == domainId || domainIdInChildreanList))) {
s_logger.error("Cannot dedicate Cluster. Its Pod is already dedicated");
HostPodVO pod = _podDao.findById(cluster.getPodId());
throw new CloudRuntimeException("Cluster's Pod " + pod.getName() + " is already dedicated");
}
}
if (dedicatedZoneOfCluster != null) {
boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfCluster.getDomainId()).contains(domainId);
//can dedicate a cluster to an account/domain if zone is dedicated to parent-domain
if (dedicatedZoneOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
|| (accountId != null && !(dedicatedZoneOfCluster.getDomainId() == domainId || domainIdInChildreanList))) {
s_logger.error("Cannot dedicate Cluster. Its zone is already dedicated");
DataCenterVO zone = _zoneDao.findById(cluster.getDataCenterId());
throw new CloudRuntimeException("Cluster's Zone "+ zone.getName() + " is already dedicated");
}
}
//check if any resource under this cluster is dedicated to different account or sub-domain
hosts = _hostDao.findByClusterId(cluster.getId());
List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
for (HostVO host : hosts) {
DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
if (dHost != null) {
if(!(childDomainIds.contains(dHost.getDomainId()))) {
throw new CloudRuntimeException("Host " + host.getName() + " under this Cluster " + cluster.getName() + " is dedicated to different account/domain");
}
/*if all dedicated resources belongs to same account and domain then we should release dedication
and make new entry for this cluster */
if (accountId != null) {
if (dHost.getAccountId() == accountId) {
hostsToRelease.add(dHost);
} else {
s_logger.error("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
throw new CloudRuntimeException("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
}
} else {
if (dHost.getAccountId() == null && dHost.getDomainId() == domainId) {
hostsToRelease.add(dHost);
}
}
}
}
for (DedicatedResourceVO dr : hostsToRelease) {
releaseDedicatedResource(null, null, null, dr.getHostId());
}
}
checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null);
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
dedicatedResource.setAccountId(accountId);
}
dedicatedResource = _dedicatedDao.persist(dedicatedResource);
} catch (Exception e) {
s_logger.error("Unable to dedicate host due to " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to dedicate cluster. Please contact Cloud Support.");
}
txn.commit();
List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
result.add(dedicatedResource);
return result;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Host")
public List<DedicatedResourceVO> dedicateHost(Long hostId, Long domainId, String accountName) {
Long accountId = null;
if(accountName != null){
Account caller = UserContext.current().getCaller();
Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
accountId = owner.getId();
}
checkAccountAndDomain(accountId, domainId);
HostVO host = _hostDao.findById(hostId);
if (host == null) {
throw new InvalidParameterValueException("Unable to find host by id " + hostId);
} else {
//check if host is of routing type
if (host.getType() != Host.Type.Routing) {
throw new CloudRuntimeException("Invalid host type for host " + host.getName());
}
DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
DedicatedResourceVO dedicatedZoneOfHost = _dedicatedDao.findByZoneId(host.getDataCenterId());
if(dedicatedHost != null) {
s_logger.error("Host "+ host.getName() + " is already dedicated");
throw new CloudRuntimeException("Host "+ host.getName() + " is already dedicated");
}
if (dedicatedClusterOfHost != null) {
boolean domainIdInChildreanList = getDomainChildIds(dedicatedClusterOfHost.getDomainId()).contains(domainId);
//can dedicate a host to an account/domain if cluster is dedicated to parent-domain
if (dedicatedClusterOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
|| (accountId != null && !(dedicatedClusterOfHost.getDomainId() == domainId || domainIdInChildreanList))) {
ClusterVO cluster = _clusterDao.findById(host.getClusterId());
s_logger.error("Host's Cluster " + cluster.getName() + " is already dedicated");
throw new CloudRuntimeException("Host's Cluster " + cluster.getName() + " is already dedicated");
}
}
if (dedicatedPodOfHost != null){
boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfHost.getDomainId()).contains(domainId);
//can dedicate a host to an account/domain if pod is dedicated to parent-domain
if (dedicatedPodOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
|| (accountId != null && !(dedicatedPodOfHost.getDomainId() == domainId || domainIdInChildreanList))) {
HostPodVO pod = _podDao.findById(host.getPodId());
s_logger.error("Host's Pod " + pod.getName() + " is already dedicated");
throw new CloudRuntimeException("Host's Pod " + pod.getName() + " is already dedicated");
}
}
if (dedicatedZoneOfHost != null) {
boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfHost.getDomainId()).contains(domainId);
//can dedicate a host to an account/domain if zone is dedicated to parent-domain
if (dedicatedZoneOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
|| (accountId != null && !(dedicatedZoneOfHost.getDomainId() == domainId || domainIdInChildreanList))) {
DataCenterVO zone = _zoneDao.findById(host.getDataCenterId());
s_logger.error("Host's Data Center " + zone.getName() + " is already dedicated");
throw new CloudRuntimeException("Host's Data Center " + zone.getName() + " is already dedicated");
}
}
}
List<Long> childDomainIds = getDomainChildIds(domainId);
childDomainIds.add(domainId);
checkHostSuitabilityForExplicitDedication(accountId, childDomainIds, hostId);
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null);
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
dedicatedResource.setAccountId(accountId);
}
dedicatedResource = _dedicatedDao.persist(dedicatedResource);
} catch (Exception e) {
s_logger.error("Unable to dedicate host due to " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to dedicate host. Please contact Cloud Support.");
}
txn.commit();
List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
result.add(dedicatedResource);
return result;
}
private List<UserVmVO> getVmsOnHost(long hostId) {
List<UserVmVO> vms = _userVmDao.listUpByHostId(hostId);
List<UserVmVO> vmsByLastHostId = _userVmDao.listByLastHostId(hostId);
if (vmsByLastHostId.size() > 0) {
// check if any VMs are within skip.counting.hours, if yes we have to consider the host.
for (UserVmVO stoppedVM : vmsByLastHostId) {
long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime()
.getTime()) / 1000;
if (secondsSinceLastUpdate < capacityReleaseInterval) {
vms.add(stoppedVM);
}
}
}
return vms;
}
private boolean checkHostSuitabilityForExplicitDedication(Long accountId, List<Long> domainIds, long hostId) {
boolean suitable = true;
List<UserVmVO> allVmsOnHost = getVmsOnHost(hostId);
if (accountId != null) {
for (UserVmVO vm : allVmsOnHost) {
if (vm.getAccountId() != accountId) {
s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " +
"running instances of another account");
throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
"running instances of another account");
}
}
} else {
for (UserVmVO vm : allVmsOnHost) {
if (!domainIds.contains(vm.getDomainId())) {
s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " +
"running instances of another domain");
throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
"running instances of another domain");
}
}
}
return suitable;
}
private boolean checkHostsSuitabilityForExplicitDedication(Long accountId, List<Long> domainIds, List<HostVO> hosts) {
boolean suitable = true;
for (HostVO host : hosts){
checkHostSuitabilityForExplicitDedication(accountId, domainIds, host.getId());
}
return suitable;
}
private void checkAccountAndDomain(Long accountId, Long domainId) {
DomainVO domain = _domainDao.findById(domainId);
if (domain == null) {
throw new InvalidParameterValueException("Unable to find the domain by id " + domainId + ", please specify valid domainId");
}
//check if account belongs to the domain id
if (accountId != null) {
AccountVO account = _accountDao.findById(accountId);
if (account == null || domainId != account.getDomainId()){
throw new InvalidParameterValueException("Please specify the domain id of the account: " + account.getAccountName());
}
}
}
private List<Long> getDomainChildIds(long domainId) {
DomainVO domainRecord = _domainDao.findById(domainId);
List<Long> domainIds = new ArrayList<Long>();
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());
}
return domainIds;
}
@Override
public DedicateZoneResponse createDedicateZoneResponse(DedicatedResources resource) {
DedicateZoneResponse dedicateZoneResponse = new DedicateZoneResponse();
DataCenterVO dc = _zoneDao.findById(resource.getDataCenterId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
dedicateZoneResponse.setId(resource.getUuid());
dedicateZoneResponse.setZoneId(dc.getUuid());
dedicateZoneResponse.setZoneName(dc.getName());
dedicateZoneResponse.setDomainId(domain.getUuid());
if (account != null) {
dedicateZoneResponse.setAccountId(account.getUuid());
}
dedicateZoneResponse.setObjectName("dedicatedzone");
return dedicateZoneResponse;
}
@Override
public DedicatePodResponse createDedicatePodResponse(DedicatedResources resource) {
DedicatePodResponse dedicatePodResponse = new DedicatePodResponse();
HostPodVO pod = _podDao.findById(resource.getPodId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
dedicatePodResponse.setId(resource.getUuid());
dedicatePodResponse.setPodId(pod.getUuid());
dedicatePodResponse.setPodName(pod.getName());
dedicatePodResponse.setDomainId(domain.getUuid());
if (account != null) {
dedicatePodResponse.setAccountId(account.getUuid());
}
dedicatePodResponse.setObjectName("dedicatedpod");
return dedicatePodResponse;
}
@Override
public DedicateClusterResponse createDedicateClusterResponse(DedicatedResources resource) {
DedicateClusterResponse dedicateClusterResponse = new DedicateClusterResponse();
ClusterVO cluster = _clusterDao.findById(resource.getClusterId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
dedicateClusterResponse.setId(resource.getUuid());
dedicateClusterResponse.setClusterId(cluster.getUuid());
dedicateClusterResponse.setClusterName(cluster.getName());
dedicateClusterResponse.setDomainId(domain.getUuid());
if (account != null) {
dedicateClusterResponse.setAccountId(account.getUuid());
}
dedicateClusterResponse.setObjectName("dedicatedcluster");
return dedicateClusterResponse;
}
@Override
public DedicateHostResponse createDedicateHostResponse(DedicatedResources resource) {
DedicateHostResponse dedicateHostResponse = new DedicateHostResponse();
HostVO host = _hostDao.findById(resource.getHostId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
dedicateHostResponse.setId(resource.getUuid());
dedicateHostResponse.setHostId(host.getUuid());
dedicateHostResponse.setHostName(host.getName());
dedicateHostResponse.setDomainId(domain.getUuid());
if (account != null) {
dedicateHostResponse.setAccountId(account.getUuid());
}
dedicateHostResponse.setObjectName("dedicatedhost");
return dedicateHostResponse;
}
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(DedicateZoneCmd.class);
cmdList.add(DedicatePodCmd.class);
cmdList.add(DedicateClusterCmd.class);
cmdList.add(DedicateHostCmd.class);
cmdList.add(ListDedicatedZonesCmd.class);
cmdList.add(ListDedicatedPodsCmd.class);
cmdList.add(ListDedicatedClustersCmd.class);
cmdList.add(ListDedicatedHostsCmd.class);
cmdList.add(ReleaseDedicatedClusterCmd.class);
cmdList.add(ReleaseDedicatedHostCmd.class);
cmdList.add(ReleaseDedicatedPodCmd.class);
cmdList.add(ReleaseDedicatedZoneCmd.class);
return cmdList;
}
@Override
public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedZones(ListDedicatedZonesCmd cmd) {
Long zoneId = cmd.getZoneId();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
if (accountName != null) {
if (domainId != null) {
Account account = _accountDao.findActiveAccount(accountName, domainId);
if (account != null) {
accountId = account.getId();
}
} else {
throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedZones(zoneId, domainId, accountId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@Override
public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedPods(ListDedicatedPodsCmd cmd) {
Long podId = cmd.getPodId();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
if (accountName != null) {
if (domainId != null) {
Account account = _accountDao.findActiveAccount(accountName, domainId);
if (account != null) {
accountId = account.getId();
}
} else {
throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedPods(podId, domainId, accountId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@Override
public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedClusters(ListDedicatedClustersCmd cmd) {
Long clusterId = cmd.getClusterId();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
if (accountName != null) {
if (domainId != null) {
Account account = _accountDao.findActiveAccount(accountName, domainId);
if (account != null) {
accountId = account.getId();
}
} else {
throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedClusters(clusterId, domainId, accountId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@Override
public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedHosts(ListDedicatedHostsCmd cmd) {
Long hostId = cmd.getHostId();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
if (accountName != null) {
if (domainId != null) {
Account account = _accountDao.findActiveAccount(accountName, domainId);
if (account != null) {
accountId = account.getId();
}
} else {
throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedHosts(hostId, domainId, accountId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE, eventDescription = "Releasing dedicated resource")
public boolean releaseDedicatedResource(Long zoneId, Long podId, Long clusterId, Long hostId) throws InvalidParameterValueException{
DedicatedResourceVO resource = null;
Long resourceId = null;
if (zoneId != null) {
resource = _dedicatedDao.findByZoneId(zoneId);
}
if (podId != null) {
resource = _dedicatedDao.findByPodId(podId);
}
if (clusterId != null) {
resource = _dedicatedDao.findByClusterId(clusterId);
}
if (hostId != null ) {
resource = _dedicatedDao.findByHostId(hostId);
}
if (resource == null){
throw new InvalidParameterValueException("No Dedicated Resource available to release");
} else {
Transaction txn = Transaction.currentTxn();
txn.start();
resourceId = resource.getId();
if (!_dedicatedDao.remove(resourceId)) {
throw new CloudRuntimeException("Failed to delete Resource " + resourceId);
}
txn.commit();
}
return true;
}
}

View File

@ -0,0 +1,63 @@
// 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 org.apache.cloudstack.dedicated.services;
import java.util.List;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedClustersCmd;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedHostsCmd;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedPodsCmd;
import org.apache.cloudstack.dedicated.api.commands.ListDedicatedZonesCmd;
import org.apache.cloudstack.dedicated.api.response.DedicateClusterResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateHostResponse;
import org.apache.cloudstack.dedicated.api.response.DedicatePodResponse;
import org.apache.cloudstack.dedicated.api.response.DedicateZoneResponse;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.DedicatedResources;
import com.cloud.utils.Pair;
import com.cloud.utils.component.PluggableService;
public interface DedicatedService extends PluggableService{
DedicatePodResponse createDedicatePodResponse(DedicatedResources resource);
DedicateClusterResponse createDedicateClusterResponse(
DedicatedResources resource);
DedicateHostResponse createDedicateHostResponse(DedicatedResources resource);
Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedPods(ListDedicatedPodsCmd cmd);
Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedHosts(ListDedicatedHostsCmd cmd);
Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedClusters(ListDedicatedClustersCmd cmd);
boolean releaseDedicatedResource(Long zoneId, Long podId, Long clusterId, Long hostId);
DedicateZoneResponse createDedicateZoneResponse(DedicatedResources resource);
Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedZones(ListDedicatedZonesCmd cmd);
List<DedicatedResourceVO> dedicateZone(Long zoneId, Long domainId, String accountName);
List<DedicatedResourceVO> dedicatePod(Long podId, Long domainId, String accountName);
List<DedicatedResourceVO> dedicateCluster(Long clusterId, Long domainId, String accountName);
List<DedicatedResourceVO> dedicateHost(Long hostId, Long domainId, String accountName);
}

View File

@ -0,0 +1,324 @@
// 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 org.apache.cloudstack.dedicated.manager;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import junit.framework.Assert;
import org.apache.cloudstack.test.utils.SpringUtils;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserContext;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.dao.UserVmDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class DedicatedApiUnitTest {
public static final Logger s_logger = Logger.getLogger(DedicatedApiUnitTest.class);
@Inject
DedicatedResourceManagerImpl _dedicatedService = new DedicatedResourceManagerImpl();
@Inject
AccountManager _acctMgr;
@Inject
AccountDao _accountDao;
@Inject
DomainDao _domainDao;
@Inject
UserVmDao _vmDao;
@Inject
DedicatedResourceDao _dedicatedDao;
@Inject
DataCenterDao _dcDao;
@Inject
HostPodDao _podDao;
@Inject
ClusterDao _clusterDao;
@Inject
HostDao _hostDao;
@Inject
ConfigurationDao _configDao;
private static long domainId = 5L;
private static long accountId = 5L;
private static String accountName = "admin";
@BeforeClass
public static void setUp() throws ConfigurationException {
}
@Before
public void testSetUp() {
ComponentContext.initComponentsLifeCycle();
AccountVO account = new AccountVO(accountName, domainId, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid");
DomainVO domain = new DomainVO("rootDomain", 5L, 5L, "networkDomain");
UserContext.registerContext(1, account, null, true);
when(_acctMgr.finalizeOwner((Account) anyObject(), anyString(), anyLong(), anyLong())).thenReturn(account);
when(_accountDao.findByIdIncludingRemoved(0L)).thenReturn(account);
when(_accountDao.findById(anyLong())).thenReturn(account);
when(_domainDao.findById(domainId)).thenReturn(domain);
}
@Test(expected = InvalidParameterValueException.class)
public void InvalidDomainIDForAccountTest() {
_dedicatedService.dedicateZone(10L, domainId, accountName);
}
@Test(expected = InvalidParameterValueException.class)
public void dedicateResourceInvalidAccountIDTest() {
_dedicatedService.dedicateZone(10L, domainId, accountName);
}
@Test
public void releaseDedicatedZoneInvalidIdTest() {
when(_dedicatedDao.findByZoneId(10L)).thenReturn(null);
try {
_dedicatedService.releaseDedicatedResource(10L, null, null, null);
} catch (InvalidParameterValueException e) {
Assert.assertTrue(e.getMessage().contains(
"No Dedicated Resource available to release"));
}
}
/* @Test
public void runDedicateZoneTest() {
DataCenterVO dc = new DataCenterVO(10L, "TestZone", "Dedicated",
"8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null,
NetworkType.Basic, null, null);
when(_dcDao.findById(10L)).thenReturn(dc);
try {
List<DedicatedResourceVO> result = _dedicatedService.dedicateZone(10L, domainId, accountName);
Assert.assertNotNull(result);
} catch (Exception e) {
s_logger.info("exception in testing dedication of zone "
+ e.toString());
}
}
@Test
public void runDedicatePodTest() {
HostPodVO pod = new HostPodVO("TestPod", 20L, "10.0.0.1", "10.0.0.0",
22, null);
when(_podDao.findById(10L)).thenReturn(pod);
try {
List<DedicatedResourceVO> result = _dedicatedService.dedicatePod(10L, domainId, accountName);
Assert.assertNotNull(result);
} catch (Exception e) {
s_logger.info("exception in testing dedication of pod "
+ e.toString());
}
}
@Test
public void runDedicateClusterTest() {
ClusterVO cluster = new ClusterVO(10L, 10L, "TestCluster");
when(_clusterDao.findById(10L)).thenReturn(cluster);
try {
List<DedicatedResourceVO> result = _dedicatedService.dedicateCluster(10L, domainId, accountName);
Assert.assertNotNull(result);
} catch (Exception e) {
s_logger.info("exception in testing dedication of cluster "
+ e.toString());
}
}
@Test
public void runDedicateHostTest() {
HostVO host = new HostVO(10L, "Host-1", Host.Type.Routing, null,
"10.0.0.0", null, null, null, null, null, null, null, null,
Status.Up, null, null, null, 10L, 10L, 30L, 10233, null, null,
null, 0, null);
when(_hostDao.findById(10L)).thenReturn(host);
try {
List<DedicatedResourceVO> result = _dedicatedService.dedicateHost(10L, domainId, accountName);
Assert.assertNotNull(result);
} catch (Exception e) {
s_logger.info("exception in testing dedication of host "
+ e.toString());
}
}
*/
@Test(expected = CloudRuntimeException.class)
public void dedicateZoneExistTest() {
DedicatedResourceVO dr = new DedicatedResourceVO(10L, null, null, null, domainId, accountId);
when(_dedicatedDao.findByZoneId(10L)).thenReturn(dr);
_dedicatedService.dedicateZone(10L, domainId, accountName);
}
@Test(expected = CloudRuntimeException.class)
public void dedicatePodExistTest() {
DedicatedResourceVO dr = new DedicatedResourceVO(null, 10L, null, null, domainId, accountId);
when(_dedicatedDao.findByPodId(10L)).thenReturn(dr);
_dedicatedService.dedicatePod(10L, domainId, accountName);
}
@Test(expected = CloudRuntimeException.class)
public void dedicateClusterExistTest() {
DedicatedResourceVO dr = new DedicatedResourceVO(null, null, 10L, null, domainId, accountId);
when(_dedicatedDao.findByClusterId(10L)).thenReturn(dr);
_dedicatedService.dedicateCluster(10L, domainId, accountName);
}
@Test(expected = CloudRuntimeException.class)
public void dedicateHostExistTest() {
DedicatedResourceVO dr = new DedicatedResourceVO(null, null, null, 10L, domainId, accountId);
when(_dedicatedDao.findByHostId(10L)).thenReturn(dr);
_dedicatedService.dedicateHost(10L, domainId, accountName);
}
@Test(expected = InvalidParameterValueException.class)
public void releaseDedicatedPodInvalidIdTest() {
when(_dedicatedDao.findByPodId(10L)).thenReturn(null);
_dedicatedService.releaseDedicatedResource(null, 10L, null, null);
}
@Test(expected = InvalidParameterValueException.class)
public void releaseDedicatedClusterInvalidIdTest() {
when(_dedicatedDao.findByClusterId(10L)).thenReturn(null);
_dedicatedService.releaseDedicatedResource(null, null, 10L, null);
}
@Test(expected = InvalidParameterValueException.class)
public void releaseDedicatedHostInvalidIdTest() {
when(_dedicatedDao.findByHostId(10L)).thenReturn(null);
_dedicatedService.releaseDedicatedResource(null, null, null, 10L);
}
@Configuration
@ComponentScan(basePackageClasses = {DedicatedResourceManagerImpl.class},
includeFilters = {@Filter(value = TestConfiguration.Library.class,
type = FilterType.CUSTOM)}, useDefaultFilters = false)
public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
@Bean
public AccountDao accountDao() {
return Mockito.mock(AccountDao.class);
}
@Bean
public DomainDao domainDao() {
return Mockito.mock(DomainDao.class);
}
@Bean
public DedicatedResourceDao dedicatedDao() {
return Mockito.mock(DedicatedResourceDao.class);
}
@Bean
public HostDao hostDao() {
return Mockito.mock(HostDao.class);
}
@Bean
public AccountManager acctManager() {
return Mockito.mock(AccountManager.class);
}
@Bean
public UserVmDao userVmDao() {
return Mockito.mock(UserVmDao.class);
}
@Bean
public DataCenterDao dataCenterDao() {
return Mockito.mock(DataCenterDao.class);
}
@Bean
public HostPodDao hostPodDao() {
return Mockito.mock(HostPodDao.class);
}
@Bean
public ClusterDao clusterDao() {
return Mockito.mock(ClusterDao.class);
}
@Bean
public ConfigurationDao configDao() {
return Mockito.mock(ConfigurationDao.class);
}
public static class Library implements TypeFilter {
@Override
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
}
}
}
}

View File

@ -0,0 +1,45 @@
<!-- 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 require
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. -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan
base-package="org.apache.cloudstack.dedicated"/>
<bean id="componentContext" class="com.cloud.utils.component.ComponentContext" />
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
<bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" />
<bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
<property name="Interceptors">
<list>
<ref bean="transactionContextBuilder" />
<ref bean="actionEventInterceptor" />
</list>
</property>
</bean>
<bean id="ConfigurationManager" class="com.cloud.configuration.ConfigurationManagerImpl">
<property name="name" value="ConfigurationManager"/>
</bean>
<bean class="org.apache.cloudstack.dedicated.DedicatedApiTestConfiguration" />
</beans>

View File

@ -35,11 +35,13 @@
<module>api/rate-limit</module>
<module>api/discovery</module>
<module>acl/static-role-based</module>
<module>affinity-group-processors/host-anti-affinity</module>
<module>affinity-group-processors/host-anti-affinity</module>
<module>affinity-group-processors/explicit-dedication</module>
<module>deployment-planners/user-concentrated-pod</module>
<module>deployment-planners/user-dispersing</module>
<module>deployment-planners/implicit-dedication</module>
<module>host-allocators/random</module>
<module>dedicated-resources</module>
<module>hypervisors/ovm</module>
<module>hypervisors/xen</module>
<module>hypervisors/kvm</module>

View File

@ -97,6 +97,8 @@ 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.DedicatedResourceVO;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
@ -255,6 +257,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
@Inject
private AffinityGroupJoinDao _affinityGroupJoinDao;
@Inject
private DedicatedResourceDao _dedicatedDao;
/* (non-Javadoc)
* @see com.cloud.api.query.QueryService#searchForUsers(org.apache.cloudstack.api.command.admin.user.ListUsersCmd)
*/
@ -2252,12 +2256,14 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
}
if (domainId != null) {
/*List all resources due to Explicit Dedication except the dedicated resources of other account
* 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) {
} 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
@ -2287,6 +2293,12 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
// remove disabled zones
sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
//remove Dedicated zones not dedicated to this domainId or subdomainId
List<Long> dedicatedZoneIds = removeDedicatedZoneNotSuitabe(domainIds);
if(!dedicatedZoneIds.isEmpty()){
sdc.addAnd("id", SearchCriteria.Op.NIN, dedicatedZoneIds.toArray(new Object[dedicatedZoneIds.size()]));
}
} 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
@ -2316,6 +2328,12 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
// remove disabled zones
sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
//remove Dedicated zones not dedicated to this domainId or subdomainId
List<Long> dedicatedZoneIds = removeDedicatedZoneNotSuitabe(domainIds);
if(!dedicatedZoneIds.isEmpty()){
sdc.addAnd("id", SearchCriteria.Op.NIN, dedicatedZoneIds.toArray(new Object[dedicatedZoneIds.size()]));
}
}
// handle available=FALSE option, only return zones with at least one VM running there
@ -2341,6 +2359,17 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
return _dcJoinDao.searchAndCount(sc, searchFilter);
}
private List<Long> removeDedicatedZoneNotSuitabe(List<Long> domainIds) {
//remove dedicated zone of other domain
List<Long> dedicatedZoneIds = new ArrayList<Long>();
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listZonesNotInDomainIds(domainIds);
for (DedicatedResourceVO dr : dedicatedResources) {
if(dr != null) {
dedicatedZoneIds.add(dr.getDataCenterId());
}
}
return dedicatedZoneIds;
}
// This method is used for permissions check for both disk and service
// offerings

View File

@ -96,6 +96,7 @@ import com.cloud.dc.DataCenterIpAddressVO;
import com.cloud.dc.DataCenterLinkLocalIpAddressVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DcDetailVO;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Pod;
import com.cloud.dc.PodVlanMapVO;
@ -310,9 +311,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
NicSecondaryIpDao _nicSecondaryIpDao;
@Inject
NicIpAliasDao _nicIpAliasDao;
@Inject
public ManagementService _mgr;
@Inject
DedicatedResourceDao _dedicatedDao;
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
@Inject protected DataCenterLinkLocalIpAddressDao _LinkLocalIpAllocDao;
@ -952,6 +954,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
throw new CloudRuntimeException("Failed to delete pod " + podId);
}
// remove from dedicated resources
DedicatedResourceVO dr = _dedicatedDao.findByPodId(podId);
if (dr != null) {
_dedicatedDao.remove(dr.getId());
}
txn.commit();
return true;
@ -1412,6 +1419,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (success) {
// delete all capacity records for the zone
_capacityDao.removeBy(null, zoneId, null, null, null);
// remove from dedicated resources
DedicatedResourceVO dr = _dedicatedDao.findByZoneId(zoneId);
if (dr != null) {
_dedicatedDao.remove(dr.getId());
}
}
txn.commit();
@ -1804,15 +1816,20 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
try {
txn.start();
// Create the new zone in the database
DataCenterVO zone = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, domain, domainId, zoneType, zoneToken, networkDomain, isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2);
DataCenterVO zone = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, null, null, zoneType, zoneToken, networkDomain, isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2);
if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
zone.setAllocationState(allocationState);
} else {
// Zone will be disabled since 3.0. Admin shoul enable it after physical network and providers setup.
// Zone will be disabled since 3.0. Admin should enable it after physical network and providers setup.
zone.setAllocationState(Grouping.AllocationState.Disabled);
}
zone = _zoneDao.persist(zone);
if (domainId != null) {
//zone is explicitly dedicated to this domain
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zone.getId(), null, null, null, domainId, null);
_dedicatedDao.persist(dedicatedResource);
}
// Create default system networks
createDefaultSystemNetworks(zone.getId());

View File

@ -0,0 +1,136 @@
// 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.dc;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="dedicated_resources")
public class DedicatedResourceVO implements DedicatedResources{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
long id;
@Column(name="data_center_id")
Long dataCenterId;
@Column(name="pod_id")
Long podId;
@Column(name="cluster_id")
Long clusterId;
@Column(name="host_id")
Long hostId;
@Column(name="uuid")
String uuid;
@Column(name = "domain_id")
private Long domainId;
@Column(name = "account_id")
private Long accountId;
public DedicatedResourceVO() {
this.uuid = UUID.randomUUID().toString();
}
public DedicatedResourceVO(Long dataCenterId, Long podId, Long clusterId, Long hostId, Long domainId, Long accountId) {
this.dataCenterId = dataCenterId;
this.podId = podId;
this.clusterId = clusterId;
this.hostId = hostId;
this.domainId = domainId;
this.accountId = accountId;
this.uuid = UUID.randomUUID().toString();
}
public long getId() {
return id;
}
public Long getDataCenterId() {
return dataCenterId;
}
public void setDataCenterId(long dataCenterId) {
this.dataCenterId = dataCenterId;
}
public Long getPodId() {
return podId;
}
public void setPodId(long podId) {
this.podId = podId;
}
public Long getClusterId() {
return clusterId;
}
public void setClusterId(long clusterId) {
this.clusterId = clusterId;
}
public Long getHostId() {
return hostId;
}
public void setHostId(long hostId) {
this.hostId = hostId;
}
public DedicatedResourceVO(long dedicatedResourceId) {
this.id = dedicatedResourceId;
}
public Long getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String getUuid() {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}

View File

@ -0,0 +1,49 @@
// 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.dc.dao;
import java.util.List;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
public interface DedicatedResourceDao extends GenericDao<DedicatedResourceVO, Long> {
DedicatedResourceVO findByZoneId(Long zoneId);
DedicatedResourceVO findByPodId(Long podId);
DedicatedResourceVO findByClusterId(Long clusterId);
DedicatedResourceVO findByHostId(Long hostId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedHosts(Long hostId, Long domainId, Long accountId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedClusters(Long clusterId, Long domainId, Long accountId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedPods(Long podId, Long domainId, Long accountId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedZones(Long dataCenterId, Long domainId, Long accountId);
List<DedicatedResourceVO> listByAccountId(Long accountId);
List<DedicatedResourceVO> listByDomainId(Long domainId);
List<DedicatedResourceVO> listZonesNotInDomainIds(List<Long> domainIds);
}

View File

@ -0,0 +1,304 @@
// 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.dc.dao;
import java.util.List;
import javax.ejb.Local;
import org.springframework.stereotype.Component;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
@Component
@Local(value={DedicatedResourceDao.class}) @DB(txn = false)
public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO, Long> implements DedicatedResourceDao {
protected final SearchBuilder<DedicatedResourceVO> ZoneSearch;
protected final SearchBuilder<DedicatedResourceVO> PodSearch;
protected final SearchBuilder<DedicatedResourceVO> ClusterSearch;
protected final SearchBuilder<DedicatedResourceVO> HostSearch;
protected SearchBuilder<DedicatedResourceVO> ListZonesByDomainIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListPodsByDomainIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListClustersByDomainIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListHostsByDomainIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListZonesByAccountIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListPodsByAccountIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListClustersByAccountIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListHostsByAccountIdSearch;
protected SearchBuilder<DedicatedResourceVO> ListAllZonesSearch;
protected SearchBuilder<DedicatedResourceVO> ListAllPodsSearch;
protected SearchBuilder<DedicatedResourceVO> ListAllClustersSearch;
protected SearchBuilder<DedicatedResourceVO> ListAllHostsSearch;
protected SearchBuilder<DedicatedResourceVO> ListByAccountId;
protected SearchBuilder<DedicatedResourceVO> ListByDomainId;
protected SearchBuilder<DedicatedResourceVO> ZoneByDomainIdsSearch;
protected DedicatedResourceDaoImpl() {
PodSearch = createSearchBuilder();
PodSearch.and("podId", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
PodSearch.done();
ZoneSearch = createSearchBuilder();
ZoneSearch.and("zoneId", ZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
ZoneSearch.done();
ClusterSearch = createSearchBuilder();
ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
ClusterSearch.done();
HostSearch = createSearchBuilder();
HostSearch.and("hostId", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
HostSearch.done();
ListZonesByDomainIdSearch = createSearchBuilder();
ListZonesByDomainIdSearch.and("zoneId", ListZonesByDomainIdSearch.entity().getDataCenterId(), SearchCriteria.Op.NNULL);
ListZonesByDomainIdSearch.and("domainId", ListZonesByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
ListZonesByDomainIdSearch.and("accountId", ListZonesByDomainIdSearch.entity().getAccountId(), SearchCriteria.Op.NULL);
ListZonesByDomainIdSearch.done();
ListZonesByAccountIdSearch = createSearchBuilder();
ListZonesByAccountIdSearch.and("zoneId", ListZonesByAccountIdSearch.entity().getDataCenterId(), SearchCriteria.Op.NNULL);
ListZonesByAccountIdSearch.and("accountId", ListZonesByAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
ListZonesByAccountIdSearch.done();
ListPodsByDomainIdSearch = createSearchBuilder();
ListPodsByDomainIdSearch.and("podId", ListPodsByDomainIdSearch.entity().getPodId(), SearchCriteria.Op.NNULL);
ListPodsByDomainIdSearch.and("domainId", ListPodsByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
ListPodsByDomainIdSearch.and("accountId", ListPodsByDomainIdSearch.entity().getAccountId(), SearchCriteria.Op.NULL);
ListPodsByDomainIdSearch.done();
ListPodsByAccountIdSearch = createSearchBuilder();
ListPodsByAccountIdSearch.and("podId", ListPodsByAccountIdSearch.entity().getPodId(), SearchCriteria.Op.NNULL);
ListPodsByAccountIdSearch.and("accountId", ListPodsByAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
ListPodsByAccountIdSearch.done();
ListClustersByDomainIdSearch = createSearchBuilder();
ListClustersByDomainIdSearch.and("clusterId", ListClustersByDomainIdSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
ListClustersByDomainIdSearch.and("domainId", ListClustersByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
ListClustersByDomainIdSearch.and("accountId", ListClustersByDomainIdSearch.entity().getAccountId(), SearchCriteria.Op.NULL);
ListClustersByDomainIdSearch.done();
ListClustersByAccountIdSearch = createSearchBuilder();
ListClustersByAccountIdSearch.and("clusterId", ListClustersByAccountIdSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
ListClustersByAccountIdSearch.and("accountId", ListClustersByAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
ListClustersByAccountIdSearch.done();
ListHostsByDomainIdSearch = createSearchBuilder();
ListHostsByDomainIdSearch.and("hostId", ListHostsByDomainIdSearch.entity().getHostId(), SearchCriteria.Op.NNULL);
ListHostsByDomainIdSearch.and("domainId", ListHostsByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
ListHostsByDomainIdSearch.and("accountId", ListHostsByDomainIdSearch.entity().getAccountId(), SearchCriteria.Op.NULL);
ListHostsByDomainIdSearch.done();
ListHostsByAccountIdSearch = createSearchBuilder();
ListHostsByAccountIdSearch.and("hostId", ListHostsByAccountIdSearch.entity().getHostId(), SearchCriteria.Op.NNULL);
ListHostsByAccountIdSearch.and("accountId", ListHostsByAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
ListHostsByAccountIdSearch.done();
ListAllZonesSearch = createSearchBuilder();
ListAllZonesSearch.and("zoneId", ListAllZonesSearch.entity().getDataCenterId(), Op.EQ);
ListAllZonesSearch.and("podId", ListAllZonesSearch.entity().getPodId(), Op.NULL);
ListAllZonesSearch.and("clusterId", ListAllZonesSearch.entity().getClusterId(), Op.NULL);
ListAllZonesSearch.and("hostId", ListAllZonesSearch.entity().getHostId(), Op.NULL);
ListAllZonesSearch.and("accountId", ListAllZonesSearch.entity().getAccountId(), Op.EQ);
ListAllZonesSearch.and("domainId", ListAllZonesSearch.entity().getDomainId(), Op.EQ);
ListAllZonesSearch.done();
ListAllPodsSearch = createSearchBuilder();
ListAllPodsSearch.and("zoneId", ListAllPodsSearch.entity().getDataCenterId(), Op.NULL);
ListAllPodsSearch.and("podId", ListAllPodsSearch.entity().getPodId(), Op.EQ);
ListAllPodsSearch.and("clusterId", ListAllPodsSearch.entity().getClusterId(), Op.NULL);
ListAllPodsSearch.and("hostId", ListAllPodsSearch.entity().getHostId(), Op.NULL);
ListAllPodsSearch.and("accountId", ListAllPodsSearch.entity().getAccountId(), Op.EQ);
ListAllPodsSearch.and("domainId", ListAllPodsSearch.entity().getDomainId(), Op.EQ);
ListAllPodsSearch.done();
ListAllClustersSearch = createSearchBuilder();
ListAllClustersSearch.and("zoneId", ListAllClustersSearch.entity().getDataCenterId(), Op.NULL);
ListAllClustersSearch.and("podId", ListAllClustersSearch.entity().getPodId(), Op.NULL);
ListAllClustersSearch.and("clusterId", ListAllClustersSearch.entity().getClusterId(), Op.EQ);
ListAllClustersSearch.and("hostId", ListAllClustersSearch.entity().getHostId(), Op.NULL);
ListAllClustersSearch.and("accountId", ListAllClustersSearch.entity().getAccountId(), Op.EQ);
ListAllClustersSearch.and("domainId", ListAllClustersSearch.entity().getDomainId(), Op.EQ);
ListAllClustersSearch.done();
ListAllHostsSearch = createSearchBuilder();
ListAllHostsSearch.and("zoneId", ListAllHostsSearch.entity().getDataCenterId(), Op.NULL);
ListAllHostsSearch.and("podId", ListAllHostsSearch.entity().getPodId(), Op.NULL);
ListAllHostsSearch.and("clusterId", ListAllHostsSearch.entity().getClusterId(), Op.NULL);
ListAllHostsSearch.and("hostId", ListAllHostsSearch.entity().getHostId(), Op.EQ);
ListAllHostsSearch.and("accountId", ListAllHostsSearch.entity().getAccountId(), Op.EQ);
ListAllHostsSearch.and("domainId", ListAllHostsSearch.entity().getDomainId(), Op.EQ);
ListAllHostsSearch.done();
ListByAccountId = createSearchBuilder();
ListByAccountId.and("accountId", ListByAccountId.entity().getAccountId(), SearchCriteria.Op.EQ);
ListByAccountId.done();
ListByDomainId = createSearchBuilder();
ListByDomainId.and("accountId", ListByDomainId.entity().getAccountId(), SearchCriteria.Op.NULL);
ListByDomainId.and("domainId", ListByDomainId.entity().getDomainId(), SearchCriteria.Op.EQ);
ListByDomainId.done();
ZoneByDomainIdsSearch = createSearchBuilder();
ZoneByDomainIdsSearch.and("zoneId", ZoneByDomainIdsSearch.entity().getDataCenterId(), SearchCriteria.Op.NNULL);
ZoneByDomainIdsSearch.and("domainId", ZoneByDomainIdsSearch.entity().getDomainId(), SearchCriteria.Op.NIN);
ZoneByDomainIdsSearch.done();
}
@Override
public DedicatedResourceVO findByZoneId(Long zoneId) {
SearchCriteria<DedicatedResourceVO> sc = ZoneSearch.create();
sc.setParameters("zoneId", zoneId);
return findOneBy(sc);
}
@Override
public DedicatedResourceVO findByPodId(Long podId) {
SearchCriteria<DedicatedResourceVO> sc = PodSearch.create();
sc.setParameters("podId", podId);
return findOneBy(sc);
}
@Override
public DedicatedResourceVO findByClusterId(Long clusterId) {
SearchCriteria<DedicatedResourceVO> sc = ClusterSearch.create();
sc.setParameters("clusterId", clusterId);
return findOneBy(sc);
}
@Override
public DedicatedResourceVO findByHostId(Long hostId) {
SearchCriteria<DedicatedResourceVO> sc = HostSearch.create();
sc.setParameters("hostId", hostId);
return findOneBy(sc);
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedZones(Long dataCenterId, Long domainId, Long accountId){
SearchCriteria<DedicatedResourceVO> sc = ListAllZonesSearch.create();
if (dataCenterId != null) {
sc.setParameters("dataCenterId", dataCenterId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
sc.setParameters("accountId", accountId);
} else {
sc.setParameters("accountId", (Object)null);
}
}
return searchAndCount(sc, null);
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedPods(Long podId, Long domainId, Long accountId){
SearchCriteria<DedicatedResourceVO> sc = ListAllPodsSearch.create();
if (podId != null) {
sc.setParameters("podId", podId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
sc.setParameters("accountId", accountId);
} else {
sc.setParameters("accountId", (Object)null);
}
}
return searchAndCount(sc, null);
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedClusters(Long clusterId, Long domainId, Long accountId){
SearchCriteria<DedicatedResourceVO> sc = ListAllClustersSearch.create();
if (clusterId != null) {
sc.setParameters("clusterId", clusterId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
sc.setParameters("accountId", accountId);
} else {
sc.setParameters("accountId", (Object)null);
}
}
return searchAndCount(sc, null);
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedHosts(Long hostId, Long domainId, Long accountId){
SearchCriteria<DedicatedResourceVO> sc = ListAllHostsSearch.create();
if (hostId != null) {
sc.setParameters("hostId", hostId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
sc.setParameters("accountId", accountId);
} else {
sc.setParameters("accountId", (Object)null);
}
}
return searchAndCount(sc, null);
}
@Override
public List<DedicatedResourceVO> listByAccountId(Long accountId){
SearchCriteria<DedicatedResourceVO> sc = ListByAccountId.create();
sc.setParameters("accountId", accountId);
return listBy(sc);
}
@Override
public List<DedicatedResourceVO> listByDomainId(Long domainId){
SearchCriteria<DedicatedResourceVO> sc = ListByDomainId.create();
sc.setParameters("domainId", domainId);
return listBy(sc);
}
@Override
public List<DedicatedResourceVO> listZonesNotInDomainIds(List<Long> domainIds) {
SearchCriteria<DedicatedResourceVO> sc = ZoneByDomainIdsSearch.create();
sc.setParameters("domainId", domainIds.toArray(new Object[domainIds.size()]));
return listBy(sc);
}
@Override
public boolean remove(Long id) {
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO resource = createForUpdate();
update(id, resource);
boolean result = super.remove(id);
txn.commit();
return result;
}
}

View File

@ -30,6 +30,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.dc.*;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
@ -84,6 +85,7 @@ import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.ClusterVSMMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterIpAddressDao;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.PlannerHostReservationVO;
import com.cloud.deploy.dao.PlannerHostReservationDao;
@ -219,6 +221,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
protected StorageService _storageSvr;
@Inject
PlannerHostReservationDao _plannerHostReserveDao;
@Inject
protected DedicatedResourceDao _dedicatedDao;
protected List<? extends Discoverer> _discoverers;
public List<? extends Discoverer> getDiscoverers() {
@ -1026,6 +1030,11 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN,
capacityTypes);
_capacityDao.remove(hostCapacitySC);
// remove from dedicated resources
DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
if (dr != null) {
_dedicatedDao.remove(dr.getId());
}
txn.commit();
return true;
}
@ -1100,11 +1109,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
&& Boolean.parseBoolean(_configDao
.getValue(Config.VmwareUseNexusVSwitch
.toString()))) {
_clusterVSMMapDao.removeByClusterId(cmd.getId());
}
}
_clusterVSMMapDao.removeByClusterId(cmd.getId());
}
// remove from dedicated resources
DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
if (dr != null) {
_dedicatedDao.remove(dr.getId());
}
}
txn.commit();
txn.commit();
return true;
} catch (CloudRuntimeException e) {
throw e;

View File

@ -61,8 +61,10 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceCountDao;
import com.cloud.configuration.dao.ResourceLimitDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterVnetDao;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
@ -229,6 +231,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
@Inject
private AffinityGroupDao _affinityGroupDao;
@Inject
private AccountGuestVlanMapDao _accountGuestVlanMapDao;
@Inject
private DataCenterVnetDao _dataCenterVnetDao;
@ -236,6 +239,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
private ResourceLimitService _resourceLimitMgr;
@Inject
private ResourceLimitDao _resourceLimitDao;
@Inject
private DedicatedResourceDao _dedicatedDao;
private List<UserAuthenticator> _userAuthenticators;
List<UserAuthenticator> _userPasswordEncoders;
@ -738,7 +743,16 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
s_logger.debug("Releasing portable ip " + ip + " as a part of account id=" + accountId + " cleanup");
_networkMgr.releasePortableIpAddress(ip.getId());
}
//release dedication if any
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByAccountId(accountId);
if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
s_logger.debug("Releasing dedicated resources for account " + accountId);
for (DedicatedResourceVO dr : dedicatedResources){
if (!_dedicatedDao.remove(dr.getId())) {
s_logger.warn("Fail to release dedicated resources for account " + accountId);
}
}
}
return true;
} catch (Exception ex) {
s_logger.warn("Failed to cleanup account " + account + " due to ", ex);
@ -1488,6 +1502,16 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
try {
List<AccountVO> accountsForCleanupInDomain = _accountDao.findCleanupsForRemovedAccounts(domainId);
if (accountsForCleanupInDomain.isEmpty()) {
//release dedication if any, before deleting the domain
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByDomainId(domainId);
if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
s_logger.debug("Releasing dedicated resources for domain" + domainId);
for (DedicatedResourceVO dr : dedicatedResources){
if (!_dedicatedDao.remove(dr.getId())) {
s_logger.warn("Fail to release dedicated resources for domain " + domainId);
}
}
}
s_logger.debug("Removing inactive domain id=" + domainId);
_domainMgr.removeDomain(domainId);
} else {

View File

@ -35,6 +35,8 @@ import com.cloud.configuration.Resource.ResourceOwnerType;
import com.cloud.configuration.ResourceLimit;
import com.cloud.configuration.dao.ResourceCountDao;
import com.cloud.configuration.dao.ResourceLimitDao;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
@ -87,6 +89,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
private RegionManager _regionMgr;
@Inject
private ResourceLimitDao _resourceLimitDao;
@Inject
private DedicatedResourceDao _dedicatedDao;
@Override
public Domain getDomain(long domainId) {
@ -237,6 +241,17 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
CloudRuntimeException e = new CloudRuntimeException("Delete failed on domain " + domain.getName() + " (id: " + domain.getId() + "); Please make sure all users and sub domains have been removed from the domain before deleting");
e.addProxyObject(domain.getUuid(), "domainId");
throw e;
} else {
//release dedication if any, before deleting the domain
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByDomainId(domain.getId());
if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
s_logger.debug("Releasing dedicated resources for domain" + domain.getId());
for (DedicatedResourceVO dr : dedicatedResources){
if (!_dedicatedDao.remove(dr.getId())) {
s_logger.warn("Fail to release dedicated resources for domain " + domain.getId());
}
}
}
}
} else {
rollBackState = true;
@ -333,6 +348,17 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
boolean deleteDomainSuccess = true;
List<AccountVO> accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domainId);
if (accountsForCleanup.isEmpty()) {
//release dedication if any, before deleting the domain
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByDomainId(domainId);
if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
s_logger.debug("Releasing dedicated resources for domain" + domainId);
for (DedicatedResourceVO dr : dedicatedResources){
if (!_dedicatedDao.remove(dr.getId())) {
s_logger.warn("Fail to release dedicated resources for domain " + domainId);
}
}
}
//delete domain
deleteDomainSuccess = _domainDao.remove(domainId);
// Delete resource count and resource limits entries set for this domain (if there are any).

View File

@ -93,9 +93,11 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
@ -402,6 +404,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
@Inject
AffinityGroupDao _affinityGroupDao;
@Inject
DedicatedResourceDao _dedicatedDao;
@Inject
ConfigurationServer _configServer;
protected ScheduledExecutorService _executor = null;
@ -2362,8 +2366,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
+ zone.getId());
}
if (zone.getDomainId() != null) {
DomainVO domain = _domainDao.findById(zone.getDomainId());
boolean isExplicit = false;
// check affinity group type Explicit dedication
if (affinityGroupIdList != null) {
for (Long affinityGroupId : affinityGroupIdList) {
AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
String agType = ag.getType();
if (agType.equals("ExplicitDedication")) {
isExplicit = true;
}
}
}
// check if zone is dedicated
DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zone.getId());
if (isExplicit && dedicatedZone != null) {
DomainVO domain = _domainDao.findById(dedicatedZone.getDomainId());
if (domain == null) {
throw new CloudRuntimeException("Unable to find the domain "
+ zone.getDomainId() + " for the zone: " + zone);
@ -3676,6 +3693,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
+ destinationHost.getResourceState());
}
HostVO srcHost = _hostDao.findById(srcHostId);
HostVO destHost = _hostDao.findById(destinationHost.getId());
//if srcHost is dedicated and destination Host is not
if (checkIfHostIsDedicated(srcHost) && !checkIfHostIsDedicated(destHost)) {
//raise an alert
String msg = "VM is migrated on a non-dedicated host " + destinationHost.getName();
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
}
//if srcHost is non dedicated but destination Host is.
if (!checkIfHostIsDedicated(srcHost) && checkIfHostIsDedicated(destHost)) {
//raise an alert
String msg = "VM is migrated on a dedicated host " + destinationHost.getName();
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
}
// call to core process
DataCenterVO dcVO = _dcDao.findById(destinationHost.getDataCenterId());
HostPodVO pod = _podDao.findById(destinationHost.getPodId());
@ -3703,6 +3735,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
return migratedVm;
}
private boolean checkIfHostIsDedicated(HostVO host) {
long hostId = host.getId();
DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
if(dedicatedHost != null || dedicatedClusterOfHost != null || dedicatedPodOfHost != null) {
return true;
} else {
return false;
}
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost,
@ -3822,7 +3866,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
VMInstanceVO migratedVm = _itMgr.migrateWithStorage(vm, srcHostId, destinationHost.getId(), volToPoolObjectMap);
return migratedVm;
}
}
@DB
@Override

View File

@ -49,6 +49,7 @@ import com.cloud.dc.dao.DataCenterIpAddressDaoImpl;
import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDao;
import com.cloud.dc.dao.DataCenterVnetDaoImpl;
import com.cloud.dc.dao.DcDetailsDaoImpl;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.dc.dao.HostPodDaoImpl;
import com.cloud.dc.dao.PodVlanDaoImpl;
import com.cloud.dc.dao.PodVlanMapDaoImpl;
@ -173,7 +174,7 @@ import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
},
includeFilters={@Filter(value=ChildTestConfiguration.Library.class, type=FilterType.CUSTOM)},
useDefaultFilters=false
)
)
public class ChildTestConfiguration {
@ -332,6 +333,11 @@ public class ChildTestConfiguration {
return Mockito.mock(NetworkDao.class);
}
@Bean
public DedicatedResourceDao DedicatedResourceDao() {
return Mockito.mock(DedicatedResourceDao.class);
}
@Bean
public NetworkOfferingServiceMapDao networkOfferingServiceMapDao() {
return Mockito.mock(NetworkOfferingServiceMapDao.class);
@ -339,7 +345,7 @@ public class ChildTestConfiguration {
@Bean
public DataCenterLinkLocalIpAddressDao datacenterLinkLocalIpAddressDao() {
return Mockito.mock(DataCenterLinkLocalIpAddressDao.class);
return Mockito.mock(DataCenterLinkLocalIpAddressDao.class);
}
@Bean
@ -357,7 +363,6 @@ public class ChildTestConfiguration {
return Mockito.mock(AccountDetailsDao.class);
}
public static class Library implements TypeFilter {
@Override

View File

@ -2453,7 +2453,6 @@ CREATE TABLE `cloud`.`resource_tags` (
CONSTRAINT `uc_resource_tags__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`external_nicira_nvp_devices` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`uuid` varchar(255) UNIQUE,

View File

@ -178,6 +178,27 @@ CREATE TABLE `cloud`.`affinity_group_vm_map` (
CREATE TABLE `cloud`.`dedicated_resources` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`uuid` varchar(40),
`data_center_id` bigint unsigned COMMENT 'data center id',
`pod_id` bigint unsigned COMMENT 'pod id',
`cluster_id` bigint unsigned COMMENT 'cluster id',
`host_id` bigint unsigned COMMENT 'host id',
`domain_id` bigint unsigned COMMENT 'domain id of the domain to which resource is dedicated',
`account_id` bigint unsigned COMMENT 'account id of the account to which resource is dedicated',
PRIMARY KEY (`id`),
CONSTRAINT `fk_dedicated_resources__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `cloud`.`data_center`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_dedicated_resources__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `cloud`.`host_pod_ref`(`id`),
CONSTRAINT `fk_dedicated_resources__cluster_id` FOREIGN KEY (`cluster_id`) REFERENCES `cloud`.`cluster`(`id`),
CONSTRAINT `fk_dedicated_resources__host_id` FOREIGN KEY (`host_id`) REFERENCES `cloud`.`host`(`id`),
CONSTRAINT `fk_dedicated_resources__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`),
CONSTRAINT `fk_dedicated_resources__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`),
INDEX `i_dedicated_resources_domain_id`(`domain_id`),
INDEX `i_dedicated_resources_account_id`(`account_id`),
CONSTRAINT `uc_dedicated_resources__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE nic_secondary_ips (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`uuid` varchar(40),
@ -203,6 +224,9 @@ ALTER TABLE `cloud`.`event` ADD COLUMN `archived` tinyint(1) unsigned NOT NULL D
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.interval', '86400', 'The interval (in seconds) to wait before running the alert purge thread');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.delay', '0', 'Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts');
INSERT INTO `cloud`.`dedicated_resources` (`data_center_id`, `domain_id`) SELECT `id`, `domain_id` FROM `cloud`.`data_center` WHERE `domain_id` IS NOT NULL;
UPDATE `cloud`.`data_center` SET `domain_id` = NULL WHERE `domain_id` IS NOT NULL;
DROP VIEW IF EXISTS `cloud`.`event_view`;
CREATE VIEW `cloud`.`event_view` AS
select
@ -1721,6 +1745,7 @@ UPDATE `cloud`.`snapshots` set swift_id=null where swift_id=0;
-- Re-enable foreign key checking, at the end of the upgrade path
SET foreign_key_checks = 1;
UPDATE `cloud`.`snapshot_policy` set uuid=id WHERE uuid is NULL;
#update shared sg enabled network with not null name in Advance Security Group enabled network
UPDATE `cloud`.`networks` set name='Shared SG enabled network', display_text='Shared SG enabled network' WHERE name IS null AND traffic_type='Guest' AND data_center_id IN (select id from data_center where networktype='Advanced' and is_security_group_enabled=1) AND acl_type='Domain';

View File

@ -0,0 +1,231 @@
# 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.
""" P1 tests for Storage motion
"""
#Import Local Modules
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.remoteSSHClient import remoteSSHClient
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
from nose.plugins.attrib import attr
#Import System modules
import time
_multiprocess_shared_ = True
class Services:
"""Test explicit dedication
"""
def __init__(self):
self.services = {
"disk_offering":{
"displaytext": "Small",
"name": "Small",
"disksize": 1
},
"account": {
"email": "test@test.com",
"firstname": "Test",
"lastname": "User",
"username": "testexplicit",
# Random characters are appended in create account to
# ensure unique username generated each time
"password": "password",
},
"virtual_machine" :
{
"affinity": {
"name": "explicit",
"type": "ExplicitDedication",
},
"hypervisor" : "XenServer",
},
"small":
# Create a small virtual machine instance with disk offering
{
"displayname": "testserver",
"username": "root", # VM creds for SSH
"password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"service_offerings":
{
"for-explicit":
{
# Small service offering ID to for change VM
# service offering from medium to small
"name": "For explicit",
"displaytext": "For explicit",
"cpunumber": 1,
"cpuspeed": 500,
"memory": 512
}
},
"template": {
"displaytext": "Cent OS Template",
"name": "Cent OS Template",
"passwordenabled": True,
},
"diskdevice": '/dev/xvdd',
# Disk device where ISO is attached to instance
"mount_dir": "/mnt/tmp",
"sleep": 60,
"timeout": 10,
"ostype": 'CentOS 5.3 (64-bit)'
}
class TestExplicitDedication(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.api_client = super(TestExplicitDedication, cls).getClsTestClient().getApiClient()
cls.services = Services().services
# Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client, cls.services)
cls.zone = get_zone(cls.api_client, cls.services)
cls.services['mode'] = cls.zone.networktype
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostype"]
)
# Set Zones and disk offerings
cls.services["small"]["zoneid"] = cls.zone.id
cls.services["small"]["template"] = cls.template.id
# Create VMs, NAT Rules etc
cls.account = Account.create(
cls.api_client,
cls.services["account"],
domainid=cls.domain.id
)
cls.small_offering = ServiceOffering.create(
cls.api_client,
cls.services["service_offerings"]["for-explicit"]
)
#cls.ag = AffinityGroup.create(cls.api_client, cls.services["virtual_machine"]["affinity"],
# account=cls.services["account"], domainid=cls.domain.id)
cls._cleanup = [
cls.small_offering,
cls.account
]
@classmethod
def tearDownClass(cls):
cls.api_client = super(TestExplicitDedication, cls).getClsTestClient().getApiClient()
cleanup_resources(cls.api_client, cls._cleanup)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.cleanup = []
def tearDown(self):
#Clean up, terminate the created ISOs
cleanup_resources(self.apiclient, self.cleanup)
return
# This test requires multi host and at least one host which is empty (no vms should
# be running on that host). It explicitly dedicates empty host to an account, deploys
# a vm for that account and verifies that the vm gets deployed to the dedicated host.
@attr(tags = ["advanced", "basic", "multihosts", "explicitdedication"])
def test_01_deploy_vm_with_explicit_dedication(self):
"""Test explicit dedication is placing vms of an account on dedicated hosts.
"""
# Validate the following
# 1. Find and dedicate an empty host to an account.
# 2. Create an affinity group for explicit dedication.
# 3. Create a vm deployment by passing the affinity group as a parameter.
# 4. Validate the vm got deployed on the dedicated host.
# 5. Cleanup.
# list and find an empty hosts
all_hosts = list_hosts(
self.apiclient,
type='Routing',
)
empty_host = None
for host in all_hosts:
vms_on_host = list_virtual_machines(
self.api_client,
hostid=host.id)
if not vms_on_host:
empty_host = host
break
# Create an affinity group for explicit dedication.
agCmd = createAffinityGroup.createAffinityGroupCmd()
agCmd.name = "explicit-affinity"
agCmd.displayText = "explicit-affinity"
agCmd.account = self.account.name
agCmd.domainid = self.account.domainid
agCmd.type = self.services['virtual_machine']['affinity']['type']
self.apiclient.createAffinityGroup(agCmd)
# dedicate the empty host to this account.
dedicateCmd = dedicateHost.dedicateHostCmd()
dedicateCmd.hostid = empty_host.id
dedicateCmd.domainid = self.domain.id
self.apiclient.dedicateHost(dedicateCmd)
# deploy vm on the dedicated resource.
vm = VirtualMachine.create(
self.api_client,
self.services["small"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.small_offering.id,
affinitygroupnames=["explicit-affinity"],
mode=self.services["mode"]
)
list_vm_response = list_virtual_machines(
self.apiclient,
id=vm.id
)
vm_response = list_vm_response[0]
self.assertEqual(
vm_response.hostid,
empty_host.id,
"Check destination hostID of deployed VM"
)
# release the dedicated host to this account.
releaseCmd = releaseDedicatedHost.releaseDedicatedHostCmd()
releaseCmd.hostid = empty_host.id
releaseCmd.domainid = self.domain.id
self.apiclient.releaseDedicatedHost(releaseCmd)
#Deletion of the created VM and affinity group is taken care as part of account clean
return

View File

@ -143,7 +143,9 @@ known_categories = {
'AffinityGroup': 'Affinity Group',
'InternalLoadBalancer': 'Internal LB',
'DeploymentPlanners': 'Configuration',
'PortableIp': 'Portable IP'
'PortableIp': 'Portable IP',
'dedicateHost': 'Dedicate Resources',
'releaseDedicatedHost': 'Dedicate Resources'
}