CLOUDSTACK-4221: Dedicated Resources: changes to associate the dedicated resource with the 'ExplicitDedication' affinity group

Changes:
- Implict creation of the 'ExplicitDedication' Affinity group during resource dedication
- Only one group per account or per domain will be present
- ListDedicatedResources by affinityGroup
- Deployment should consider dedicated resources associated to the group only
- Deleting affinity group should release the dedicated resouces
- Releasing the dedicated resources should remove the group associated if there are no more resources.

Conflicts:

	plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
	plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
	server/src/com/cloud/configuration/ConfigurationManagerImpl.java
This commit is contained in:
Prachi Damle 2013-09-03 13:25:22 -07:00
parent a06bd9fa2b
commit ef22b42b38
26 changed files with 803 additions and 197 deletions

View File

@ -29,5 +29,5 @@ public interface DedicatedResources extends InfrastructureEntity, InternalIdenti
Long getDomainId();
Long getAccountId();
String getUuid();
long getAffinityGroupId();
}

View File

@ -72,9 +72,20 @@ public interface AffinityGroupProcessor extends Adapter {
* canBeSharedDomainWide() should return true if the affinity/anti-affinity
* group can be created for a domain and shared by all accounts under the
* domain.
*
*
* @return boolean true/false
*/
boolean canBeSharedDomainWide();
/**
* subDomainAccess() should return true if the affinity/anti-affinity group
* can be created for a domain and used by the sub-domains. If true, all
* accounts under the sub-domains can see this group and use it.
*
* @return boolean true/false
*/
boolean subDomainAccess();
void handleDeleteGroup(AffinityGroup group);
}

View File

@ -57,4 +57,15 @@ public class AffinityProcessorBase extends AdapterBase implements AffinityGroupP
public boolean canBeSharedDomainWide() {
return false;
}
@Override
public void handleDeleteGroup(AffinityGroup group) {
// TODO Auto-generated method stub
return;
}
@Override
public boolean subDomainAccess() {
return false;
}
}

View File

@ -75,8 +75,9 @@ public class Upgrade410to420 implements DbUpgrade {
return new File[] { new File(script) };
}
@Override
public void performDataMigration(Connection conn) {
@Override
public void performDataMigration(Connection conn) {
movePrivateZoneToDedicatedResource(conn);
upgradeVmwareLabels(conn);
persistLegacyZones(conn);
persistVswitchConfiguration(conn);
@ -262,6 +263,126 @@ public class Upgrade410to420 implements DbUpgrade {
}
}
private void movePrivateZoneToDedicatedResource(Connection conn) {
PreparedStatement pstmt = null;
ResultSet rs = null;
PreparedStatement pstmtUpdate = null;
try {
pstmt = conn.prepareStatement("SELECT `id`, `domain_id` FROM `cloud`.`data_center` WHERE `domain_id` IS NOT NULL");
rs = pstmt.executeQuery();
while (rs.next()) {
long zoneId = rs.getLong(1);
long domainId = rs.getLong(2);
long affinityGroupId;
// create or find an affinity group for this domain of type
// 'ExplicitDedication'
PreparedStatement pstmt2 = null;
ResultSet rs2 = null;
pstmt2 = conn
.prepareStatement("SELECT affinity_group.id FROM `cloud`.`affinity_group` INNER JOIN `cloud`.`affinity_group_domain_map` ON affinity_group.id=affinity_group_domain_map.affinity_group_id WHERE affinity_group.type = 'ExplicitDedication' AND affinity_group.acl_type = 'Domain' AND (affinity_group_domain_map.domain_id = ?)");
pstmt2.setLong(1, domainId);
rs2 = pstmt2.executeQuery();
if (rs2.next()) {
// group exists, use it
affinityGroupId = rs2.getLong(1);
dedicateZone(conn, zoneId, domainId, affinityGroupId);
} else {
// create new group
rs2.close();
pstmt2.close();
pstmt2 = conn.prepareStatement("SELECT name FROM `cloud`.`domain` where id = ?");
pstmt2.setLong(1, domainId);
rs2 = pstmt2.executeQuery();
String domainName = "";
if (rs2.next()) {
// group exists, use it
domainName = rs2.getString(1);
}
rs2.close();
pstmt2.close();
// create new domain level group for this domain
String type = "ExplicitDedication";
String uuid = UUID.randomUUID().toString();
String groupName = "DedicatedGrp-domain-" + domainName;
s_logger.debug("Adding AffinityGroup of type " + type + " for domain id " + domainId);
String sql = "INSERT INTO `cloud`.`affinity_group` (`name`, `type`, `uuid`, `description`, `domain_id`, `account_id`, `acl_type`) VALUES (?, ?, ?, ?, 1, 1, 'Domain')";
pstmtUpdate = conn.prepareStatement(sql);
pstmtUpdate.setString(1, groupName);
pstmtUpdate.setString(2, type);
pstmtUpdate.setString(3, uuid);
pstmtUpdate.setString(4, "dedicated resources group");
pstmtUpdate.executeUpdate();
pstmtUpdate.close();
pstmt2 = conn
.prepareStatement("SELECT affinity_group.id FROM `cloud`.`affinity_group` where uuid = ?");
pstmt2.setString(1, uuid);
rs2 = pstmt2.executeQuery();
if (rs2.next()) {
affinityGroupId = rs2.getLong(1);
dedicateZone(conn, zoneId, domainId, affinityGroupId);
}
}
rs2.close();
pstmt2.close();
}
} catch (SQLException e) {
throw new CloudRuntimeException("Exception while Moving private zone information to dedicated resources", e);
} finally {
if (pstmtUpdate != null) {
try {
pstmtUpdate.close();
} catch (SQLException e) {
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
}
}
}
}
private void dedicateZone(Connection conn, long zoneId, long domainId, long affinityGroupId) {
PreparedStatement pstmtUpdate2 = null;
try {
// create the dedicated resources entry
String sql = "INSERT INTO `cloud`.`dedicated_resources` (`uuid`,`data_center_id`, `domain_id`, `affinity_group_id`) VALUES (?, ?, ?, ?)";
pstmtUpdate2 = conn.prepareStatement(sql);
pstmtUpdate2.setString(1, UUID.randomUUID().toString());
pstmtUpdate2.setLong(2, zoneId);
pstmtUpdate2.setLong(3, domainId);
pstmtUpdate2.setLong(4, affinityGroupId);
pstmtUpdate2.executeUpdate();
pstmtUpdate2.close();
} catch (SQLException e) {
throw new CloudRuntimeException("Exception while saving zone to dedicated resources", e);
} finally {
if (pstmtUpdate2 != null) {
try {
pstmtUpdate2.close();
} catch (SQLException e) {
}
}
}
}
private void fixBaremetalForeignKeys(Connection conn) {
List<String> keys = new ArrayList<String>();
keys.add("fk_external_dhcp_devices_nsp_id");

View File

@ -18,6 +18,7 @@ package org.apache.cloudstack.affinity.dao;
import java.util.List;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupVO;
import com.cloud.utils.db.GenericDao;
@ -26,5 +27,12 @@ public interface AffinityGroupDao extends GenericDao<AffinityGroupVO, Long> {
boolean isNameInUse(Long accountId, Long domainId, String name);
AffinityGroupVO findByAccountAndName(Long accountId, String name);
List<AffinityGroupVO> findByAccountAndNames(Long accountId, String... names);
int removeByAccountId(long accountId);
int removeByAccountId(long accountId);
AffinityGroup findDomainLevelGroupByName(Long domainId, String affinityGroupName);
AffinityGroup findByAccountAndType(Long accountId, String string);
AffinityGroup findDomainLevelGroupByType(Long domainId, String string);
}

View File

@ -20,18 +20,29 @@ import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
import org.apache.cloudstack.affinity.AffinityGroupVO;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.JoinBuilder.JoinType;
@Local(value = { AffinityGroupDao.class })
public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long> implements AffinityGroupDao {
private SearchBuilder<AffinityGroupVO> AccountIdSearch;
private SearchBuilder<AffinityGroupVO> AccountIdNameSearch;
private SearchBuilder<AffinityGroupVO> AccountIdNamesSearch;
private SearchBuilder<AffinityGroupVO> DomainLevelNameSearch;
private SearchBuilder<AffinityGroupVO> AccountIdTypeSearch;
@Inject
AffinityGroupDomainMapDao _groupDomainDao;
private SearchBuilder<AffinityGroupVO> DomainLevelTypeSearch;
public AffinityGroupDaoImpl() {
@ -51,6 +62,30 @@ public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long>
AccountIdNamesSearch.and("accountId", AccountIdNamesSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountIdNamesSearch.and("groupNames", AccountIdNamesSearch.entity().getName(), SearchCriteria.Op.IN);
AccountIdNameSearch.done();
SearchBuilder<AffinityGroupDomainMapVO> domainMapSearch = _groupDomainDao.createSearchBuilder();
domainMapSearch.and("domainId", domainMapSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
DomainLevelNameSearch = createSearchBuilder();
DomainLevelNameSearch.and("name", DomainLevelNameSearch.entity().getName(), SearchCriteria.Op.EQ);
DomainLevelNameSearch.and("aclType", DomainLevelNameSearch.entity().getAclType(), SearchCriteria.Op.EQ);
DomainLevelNameSearch.join("domainMapSearch", domainMapSearch, domainMapSearch.entity().getAffinityGroupId(),
DomainLevelNameSearch.entity().getId(), JoinType.INNER);
DomainLevelNameSearch.done();
AccountIdTypeSearch = createSearchBuilder();
AccountIdTypeSearch.and("accountId", AccountIdTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountIdTypeSearch.and("type", AccountIdTypeSearch.entity().getType(), SearchCriteria.Op.EQ);
SearchBuilder<AffinityGroupDomainMapVO> domainTypeSearch = _groupDomainDao.createSearchBuilder();
domainTypeSearch.and("domainId", domainTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
DomainLevelTypeSearch = createSearchBuilder();
DomainLevelTypeSearch.and("type", DomainLevelTypeSearch.entity().getType(), SearchCriteria.Op.EQ);
DomainLevelTypeSearch.and("aclType", DomainLevelTypeSearch.entity().getAclType(), SearchCriteria.Op.EQ);
DomainLevelTypeSearch.join("domainTypeSearch", domainTypeSearch,
domainTypeSearch.entity().getAffinityGroupId(),
DomainLevelTypeSearch.entity().getId(), JoinType.INNER);
DomainLevelTypeSearch.done();
}
@Override
@ -99,4 +134,31 @@ public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long>
sc.setParameters("accountId", accountId);
return expunge(sc);
}
@Override
public AffinityGroup findDomainLevelGroupByName(Long domainId, String affinityGroupName) {
SearchCriteria<AffinityGroupVO> sc = DomainLevelNameSearch.create();
sc.setParameters("aclType", ControlledEntity.ACLType.Domain);
sc.setParameters("name", affinityGroupName);
sc.setJoinParameters("domainMapSearch", "domainId", domainId);
return findOneBy(sc);
}
@Override
public AffinityGroup findByAccountAndType(Long accountId, String type) {
SearchCriteria<AffinityGroupVO> sc = AccountIdTypeSearch.create();
sc.setParameters("accountId", accountId);
sc.setParameters("type", type);
return findOneBy(sc);
}
@Override
public AffinityGroup findDomainLevelGroupByType(Long domainId, String type) {
SearchCriteria<AffinityGroupVO> sc = DomainLevelTypeSearch.create();
sc.setParameters("aclType", ControlledEntity.ACLType.Domain);
sc.setParameters("type", type);
sc.setJoinParameters("domainTypeSearch", "domainId", domainId);
return findOneBy(sc);
}
}

View File

@ -44,6 +44,9 @@ 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.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
@ -88,161 +91,173 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement
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();
List<DedicatedResourceVO> resourceList = new ArrayList<DedicatedResourceVO>();
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());
s_logger.debug("Processing affinity group " + vmGroupMapping.getAffinityGroupId()
+ "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>();
long affinityGroupId = vmGroupMapping.getAffinityGroupId();
// List<DedicatedResourceVO> dr = _dedicatedDao.listByAccountId(accountId);
// List<DedicatedResourceVO> drOfDomain =
// searchInDomainResources(domainId);
// List<DedicatedResourceVO> drOfParentDomain =
// searchInParentDomainResources(domainId);
List<DedicatedResourceVO> dr = _dedicatedDao.listByAffinityGroupId(affinityGroupId);
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);
}
}
}
boolean canUse = false;
}
}
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());
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 (resourceList != null && resourceList.size() != 0) {
avoid = updateAvoidList(resourceList, 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 under this group");
}
}
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) {
@ -390,4 +405,43 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement
public boolean canBeSharedDomainWide() {
return true;
}
@Override
public void handleDeleteGroup(AffinityGroup group) {
// When a group of the 'ExplicitDedication' type gets deleted, make sure
// to remove the dedicated resources in the group as well.
if (group != null) {
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByAffinityGroupId(group.getId());
if (!dedicatedResources.isEmpty()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Releasing the dedicated resources under group: " + group);
}
Transaction txn = Transaction.currentTxn();
txn.start();
SearchBuilder<DedicatedResourceVO> listByAffinityGroup = _dedicatedDao.createSearchBuilder();
listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(),
SearchCriteria.Op.EQ);
listByAffinityGroup.done();
SearchCriteria<DedicatedResourceVO> sc = listByAffinityGroup.create();
sc.setParameters("affinityGroupId", group.getId());
_dedicatedDao.lockRows(sc, null, true);
_dedicatedDao.remove(sc);
txn.commit();
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("No dedicated resources to releease under group: " + group);
}
}
}
return;
}
@Override
public boolean subDomainAccess() {
return true;
}
}

View File

@ -21,12 +21,14 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
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.BaseCmd.CommandType;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
@ -60,6 +62,9 @@ public class ListDedicatedClustersCmd extends BaseListCmd {
description = "the name of the account associated with the cluster. Must be used with domainId.")
private String accountName;
@Parameter(name = ApiConstants.AFFINITY_GROUP_ID, type = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "list dedicated clusters by affinity group")
private Long affinityGroupId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -76,6 +81,10 @@ public class ListDedicatedClustersCmd extends BaseListCmd {
return accountName;
}
public Long getAffinityGroupId() {
return affinityGroupId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -21,12 +21,14 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
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.BaseCmd.CommandType;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ListResponse;
@ -60,6 +62,9 @@ public class ListDedicatedHostsCmd extends BaseListCmd {
description = "the name of the account associated with the host. Must be used with domainId.")
private String accountName;
@Parameter(name = ApiConstants.AFFINITY_GROUP_ID, type = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "list dedicated hosts by affinity group")
private Long affinityGroupId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -76,6 +81,10 @@ public class ListDedicatedHostsCmd extends BaseListCmd {
return accountName;
}
public Long getAffinityGroupId() {
return affinityGroupId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////l
/////////////////////////////////////////////////////

View File

@ -21,12 +21,14 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
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.BaseCmd.CommandType;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PodResponse;
@ -60,6 +62,9 @@ public class ListDedicatedPodsCmd extends BaseListCmd {
description = "the name of the account associated with the pod. Must be used with domainId.")
private String accountName;
@Parameter(name = ApiConstants.AFFINITY_GROUP_ID, type = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "list dedicated pods by affinity group")
private Long affinityGroupId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -76,6 +81,10 @@ public class ListDedicatedPodsCmd extends BaseListCmd {
return accountName;
}
public Long getAffinityGroupId() {
return affinityGroupId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -21,12 +21,14 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
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.BaseCmd.CommandType;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
@ -60,6 +62,9 @@ public class ListDedicatedZonesCmd extends BaseListCmd {
description = "the name of the account associated with the zone. Must be used with domainId.")
private String accountName;
@Parameter(name = ApiConstants.AFFINITY_GROUP_ID, type = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "list dedicated zones by affinity group")
private Long affinityGroupId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -76,6 +81,10 @@ public class ListDedicatedZonesCmd extends BaseListCmd {
return accountName;
}
public Long getAffinityGroupId() {
return affinityGroupId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.api.response;
import javax.persistence.Column;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
@ -37,6 +39,10 @@ public class DedicateClusterResponse extends BaseResponse {
@SerializedName("accountid") @Param(description="the Account ID of the cluster")
private String accountId;
@SerializedName("affinitygroupid")
@Param(description = "the Dedication Affinity Group ID of the cluster")
private String affinityGroupId;
public String getId() {
return id;
}
@ -76,4 +82,12 @@ public class DedicateClusterResponse extends BaseResponse {
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getAffinityGroupId() {
return affinityGroupId;
}
public void setAffinityGroupId(String affinityGroupId) {
this.affinityGroupId = affinityGroupId;
}
}

View File

@ -37,6 +37,10 @@ public class DedicateHostResponse extends BaseResponse {
@SerializedName("accountid") @Param(description="the Account ID of the host")
private String accountId;
@SerializedName("affinitygroupid")
@Param(description = "the Dedication Affinity Group ID of the host")
private String affinityGroupId;
public String getId() {
return id;
}
@ -76,4 +80,12 @@ public class DedicateHostResponse extends BaseResponse {
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getAffinityGroupId() {
return affinityGroupId;
}
public void setAffinityGroupId(String affinityGroupId) {
this.affinityGroupId = affinityGroupId;
}
}

View File

@ -40,6 +40,10 @@ public class DedicatePodResponse extends BaseResponse {
@SerializedName("accountid") @Param(description="the Account Id to which the Pod is dedicated")
private String accountId;
@SerializedName("affinitygroupid")
@Param(description = "the Dedication Affinity Group ID of the pod")
private String affinityGroupId;
public String getId() {
return id;
}
@ -79,4 +83,12 @@ public class DedicatePodResponse extends BaseResponse {
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getAffinityGroupId() {
return affinityGroupId;
}
public void setAffinityGroupId(String affinityGroupId) {
this.affinityGroupId = affinityGroupId;
}
}

View File

@ -40,6 +40,10 @@ public class DedicateZoneResponse extends BaseResponse {
@SerializedName("accountid") @Param(description="the Account Id to which the Zone is dedicated")
private String accountId;
@SerializedName("affinitygroupid")
@Param(description = "the Dedication Affinity Group ID of the zone")
private String affinityGroupId;
public String getId() {
return id;
}
@ -80,4 +84,11 @@ public class DedicateZoneResponse extends BaseResponse {
this.accountId = accountId;
}
public String getAffinityGroupId() {
return affinityGroupId;
}
public void setAffinityGroupId(String affinityGroupId) {
this.affinityGroupId = affinityGroupId;
}
}

View File

@ -26,6 +26,10 @@ import javax.naming.ConfigurationException;
import com.cloud.utils.component.AdapterBase;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.api.commands.DedicateClusterCmd;
import org.apache.cloudstack.api.commands.DedicateHostCmd;
import org.apache.cloudstack.api.commands.DedicatePodCmd;
@ -94,6 +98,10 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
@Inject AccountManager _accountMgr;
@Inject UserVmDao _userVmDao;
@Inject ConfigurationDao _configDao;
@Inject AffinityGroupDao _affinityGroupDao;
@Inject
AffinityGroupService _affinityGroupService;
private int capacityReleaseInterval;
@ -214,7 +222,15 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null);
// find or create the affinity group by name under this account/domain
AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId);
if (group == null) {
s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
}
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null,
group.getId());
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
@ -331,7 +347,14 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null);
// find or create the affinity group by name under this account/domain
AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId);
if (group == null) {
s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
}
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null,
group.getId());
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
@ -434,7 +457,14 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null);
// find or create the affinity group by name under this account/domain
AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId);
if (group == null) {
s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
}
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null,
group.getId());
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
@ -522,7 +552,14 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Transaction txn = Transaction.currentTxn();
txn.start();
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null);
// find or create the affinity group by name under this account/domain
AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId);
if (group == null) {
s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
}
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null,
group.getId());
try {
dedicatedResource.setDomainId(domainId);
if (accountId != null) {
@ -540,6 +577,45 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
return result;
}
private AffinityGroup findOrCreateDedicatedAffinityGroup(Long domainId, Long accountId) {
if(domainId == null){
return null;
}
AffinityGroup group = null;
String accountName = null;
String affinityGroupName = null;
if (accountId != null) {
AccountVO account = _accountDao.findById(accountId);
accountName = account.getAccountName();
group = _affinityGroupDao.findByAccountAndType(accountId, "ExplicitDedication");
if (group != null) {
return group;
}
// default to a groupname with account/domain information
affinityGroupName = "DedicatedGrp-" + accountName;
} else {
// domain level group
group = _affinityGroupDao.findDomainLevelGroupByType(domainId, "ExplicitDedication");
if (group != null) {
return group;
}
// default to a groupname with account/domain information
String domainName = _domainDao.findById(domainId).getName();
affinityGroupName = "DedicatedGrp-domain-" + domainName;
}
group = _affinityGroupService.createAffinityGroup(accountName, domainId, affinityGroupName,
"ExplicitDedication", "dedicated resources group");
return group;
}
private List<UserVmVO> getVmsOnHost(long hostId) {
List<UserVmVO> vms = _userVmDao.listUpByHostId(hostId);
List<UserVmVO> vmsByLastHostId = _userVmDao.listByLastHostId(hostId);
@ -622,10 +698,12 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
DataCenterVO dc = _zoneDao.findById(resource.getDataCenterId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
dedicateZoneResponse.setId(resource.getUuid());
dedicateZoneResponse.setZoneId(dc.getUuid());
dedicateZoneResponse.setZoneName(dc.getName());
dedicateZoneResponse.setDomainId(domain.getUuid());
dedicateZoneResponse.setAffinityGroupId(group.getUuid());
if (account != null) {
dedicateZoneResponse.setAccountId(account.getUuid());
}
@ -639,10 +717,12 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
HostPodVO pod = _podDao.findById(resource.getPodId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
dedicatePodResponse.setId(resource.getUuid());
dedicatePodResponse.setPodId(pod.getUuid());
dedicatePodResponse.setPodName(pod.getName());
dedicatePodResponse.setDomainId(domain.getUuid());
dedicatePodResponse.setAffinityGroupId(group.getUuid());
if (account != null) {
dedicatePodResponse.setAccountId(account.getUuid());
}
@ -656,10 +736,12 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
ClusterVO cluster = _clusterDao.findById(resource.getClusterId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
dedicateClusterResponse.setId(resource.getUuid());
dedicateClusterResponse.setClusterId(cluster.getUuid());
dedicateClusterResponse.setClusterName(cluster.getName());
dedicateClusterResponse.setDomainId(domain.getUuid());
dedicateClusterResponse.setAffinityGroupId(group.getUuid());
if (account != null) {
dedicateClusterResponse.setAccountId(account.getUuid());
}
@ -673,10 +755,12 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
HostVO host = _hostDao.findById(resource.getHostId());
DomainVO domain = _domainDao.findById(resource.getDomainId());
AccountVO account = _accountDao.findById(resource.getAccountId());
AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
dedicateHostResponse.setId(resource.getUuid());
dedicateHostResponse.setHostId(host.getUuid());
dedicateHostResponse.setHostName(host.getName());
dedicateHostResponse.setDomainId(domain.getUuid());
dedicateHostResponse.setAffinityGroupId(group.getUuid());
if (account != null) {
dedicateHostResponse.setAccountId(account.getUuid());
}
@ -708,6 +792,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
Long affinityGroupId = cmd.getAffinityGroupId();
if (accountName != null) {
if (domainId != null) {
Account account = _accountDao.findActiveAccount(accountName, domainId);
@ -718,7 +804,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedZones(zoneId, domainId, accountId);
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedZones(zoneId, domainId,
accountId, affinityGroupId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@ -728,6 +815,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
Long affinityGroupId = cmd.getAffinityGroupId();
if (accountName != null) {
if (domainId != null) {
Account account = _accountDao.findActiveAccount(accountName, domainId);
@ -738,7 +827,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedPods(podId, domainId, accountId);
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedPods(podId, domainId, accountId,
affinityGroupId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@ -748,6 +838,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
Long affinityGroupId = cmd.getAffinityGroupId();
if (accountName != null) {
if (domainId != null) {
Account account = _accountDao.findActiveAccount(accountName, domainId);
@ -758,7 +850,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedClusters(clusterId, domainId, accountId);
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedClusters(clusterId, domainId,
accountId, affinityGroupId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@ -767,6 +860,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
Long hostId = cmd.getHostId();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long affinityGroupId = cmd.getAffinityGroupId();
Long accountId = null;
if (accountName != null) {
if (domainId != null) {
@ -779,7 +874,7 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
}
}
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedHosts(hostId, domainId, accountId);
Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedHosts(hostId, domainId, accountId, affinityGroupId);
return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
}
@ -811,6 +906,16 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
throw new CloudRuntimeException("Failed to delete Resource " + resourceId);
}
txn.commit();
// find the group associated and check if there are any more
// resources under that group
List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource
.getAffinityGroupId());
if (resourcesInGroup.isEmpty()) {
// delete the group
_affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null);
}
}
return true;
}

View File

@ -28,6 +28,10 @@ import javax.inject.Inject;
import junit.framework.Assert;
import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.dedicated.DedicatedResourceManagerImpl;
import org.apache.cloudstack.test.utils.SpringUtils;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
@ -212,28 +216,28 @@ public class DedicatedApiUnitTest {
@Test(expected = CloudRuntimeException.class)
public void dedicateZoneExistTest() {
DedicatedResourceVO dr = new DedicatedResourceVO(10L, null, null, null, domainId, accountId);
DedicatedResourceVO dr = new DedicatedResourceVO(10L, null, null, null, domainId, accountId, 12L);
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);
DedicatedResourceVO dr = new DedicatedResourceVO(null, 10L, null, null, domainId, accountId, 12L);
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);
DedicatedResourceVO dr = new DedicatedResourceVO(null, null, 10L, null, domainId, accountId, 12L);
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);
DedicatedResourceVO dr = new DedicatedResourceVO(null, null, null, 10L, domainId, accountId, 12L);
when(_dedicatedDao.findByHostId(10L)).thenReturn(dr);
_dedicatedService.dedicateHost(10L, domainId, accountName);
}
@ -310,6 +314,16 @@ public class DedicatedApiUnitTest {
return Mockito.mock(ConfigurationDao.class);
}
@Bean
public AffinityGroupService affinityGroupService() {
return Mockito.mock(AffinityGroupService.class);
}
@Bean
public AffinityGroupDao affinityGroupDao() {
return Mockito.mock(AffinityGroupDao.class);
}
public static class Library implements TypeFilter {
@Override
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {

View File

@ -69,6 +69,8 @@ public class AffinityGroupAccessChecker extends DomainChecker {
if (caller.getId() != group.getAccountId()) {
throw new PermissionDeniedException(caller
+ " does not have permission to operate with resource " + entity);
}else{
return true;
}
}

View File

@ -41,6 +41,10 @@ import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.api.ApiConstants.LDAPParams;
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
@ -301,6 +305,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
DedicatedResourceDao _dedicatedDao;
@Inject
IpAddressManager _ipAddrMgr;
@Inject
AffinityGroupDao _affinityGroupDao;
@Inject
AffinityGroupService _affinityGroupService;
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
@Inject
@ -1799,8 +1807,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
zone = _zoneDao.persist(zone);
if (domainId != null) {
// zone is explicitly dedicated to this domain
// create affinity group associated.
AffinityGroup group = createDedicatedAffinityGroup(null, domainId, null);
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zone.getId(), null, null, null,
domainId, null);
domainId, null, group.getId());
_dedicatedDao.persist(dedicatedResource);
}
@ -1817,6 +1827,38 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
}
private AffinityGroup createDedicatedAffinityGroup(String affinityGroupName, Long domainId, Long accountId) {
if (affinityGroupName == null) {
// default to a groupname with account/domain information
affinityGroupName = "ZoneDedicatedGrp-domain-" + domainId + (accountId != null ? "-acct-" + accountId : "");
}
AffinityGroup group = null;
String accountName = null;
if (accountId != null) {
AccountVO account = _accountDao.findById(accountId);
accountName = account.getAccountName();
group = _affinityGroupDao.findByAccountAndName(accountId, affinityGroupName);
if (group != null) {
return group;
}
} else {
// domain level group
group = _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName);
if (group != null) {
return group;
}
}
group = _affinityGroupService.createAffinityGroup(accountName, domainId, affinityGroupName,
"ExplicitDedication", "dedicated resources group");
return group;
}
@Override
public void createDefaultSystemNetworks(long zoneId) throws ConcurrentOperationException {
DataCenterVO zone = _zoneDao.findById(zoneId);

View File

@ -56,11 +56,15 @@ public class DedicatedResourceVO implements DedicatedResources{
@Column(name = "account_id")
private Long accountId;
@Column(name = "affinity_group_id")
private long affinityGroupId;
public DedicatedResourceVO() {
this.uuid = UUID.randomUUID().toString();
}
public DedicatedResourceVO(Long dataCenterId, Long podId, Long clusterId, Long hostId, Long domainId, Long accountId) {
public DedicatedResourceVO(Long dataCenterId, Long podId, Long clusterId, Long hostId, Long domainId,
Long accountId, long affinityGroupId) {
this.dataCenterId = dataCenterId;
this.podId = podId;
this.clusterId = clusterId;
@ -68,6 +72,7 @@ public class DedicatedResourceVO implements DedicatedResources{
this.domainId = domainId;
this.accountId = accountId;
this.uuid = UUID.randomUUID().toString();
this.affinityGroupId = affinityGroupId;
}
public long getId() {
@ -133,4 +138,8 @@ public class DedicatedResourceVO implements DedicatedResources{
public void setUuid(String uuid) {
this.uuid = uuid;
}
public long getAffinityGroupId() {
return affinityGroupId;
}
}

View File

@ -33,13 +33,13 @@ public interface DedicatedResourceDao extends GenericDao<DedicatedResourceVO, Lo
DedicatedResourceVO findByHostId(Long hostId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedHosts(Long hostId, Long domainId, Long accountId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedHosts(Long hostId, Long domainId, Long accountId, Long affinityGroupId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedClusters(Long clusterId, Long domainId, Long accountId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedClusters(Long clusterId, Long domainId, Long accountId, Long affinityGroupId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedPods(Long podId, Long domainId, Long accountId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedPods(Long podId, Long domainId, Long accountId, Long affinityGroupId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedZones(Long dataCenterId, Long domainId, Long accountId);
Pair<List<DedicatedResourceVO>, Integer> searchDedicatedZones(Long dataCenterId, Long domainId, Long accountId, Long affinityGroupId);
List<DedicatedResourceVO> listByAccountId(Long accountId);
@ -52,4 +52,7 @@ public interface DedicatedResourceDao extends GenericDao<DedicatedResourceVO, Lo
List<Long> listAllClusters();
List<Long> listAllHosts();
List<DedicatedResourceVO> listByAffinityGroupId(Long affinityGroupId);
}

View File

@ -59,7 +59,7 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
protected SearchBuilder<DedicatedResourceVO> ListByAccountId;
protected SearchBuilder<DedicatedResourceVO> ListByDomainId;
protected SearchBuilder<DedicatedResourceVO> ListByAffinityGroupId;
protected SearchBuilder<DedicatedResourceVO> ZoneByDomainIdsSearch;
protected GenericSearchBuilder<DedicatedResourceVO, Long> ListPodsSearch;
@ -134,6 +134,7 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
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.and("affinityGroupId", ListAllZonesSearch.entity().getAffinityGroupId(), Op.EQ);
ListAllZonesSearch.done();
ListAllPodsSearch = createSearchBuilder();
@ -143,6 +144,7 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
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.and("affinityGroupId", ListAllPodsSearch.entity().getAffinityGroupId(), Op.EQ);
ListAllPodsSearch.done();
ListAllClustersSearch = createSearchBuilder();
@ -152,6 +154,7 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
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.and("affinityGroupId", ListAllClustersSearch.entity().getAffinityGroupId(), Op.EQ);
ListAllClustersSearch.done();
ListAllHostsSearch = createSearchBuilder();
@ -161,6 +164,7 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
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.and("affinityGroupId", ListAllHostsSearch.entity().getAffinityGroupId(), Op.EQ);
ListAllHostsSearch.done();
ListByAccountId = createSearchBuilder();
@ -172,6 +176,11 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
ListByDomainId.and("domainId", ListByDomainId.entity().getDomainId(), SearchCriteria.Op.EQ);
ListByDomainId.done();
ListByAffinityGroupId = createSearchBuilder();
ListByAffinityGroupId.and("affinityGroupId", ListByAffinityGroupId.entity().getAffinityGroupId(),
SearchCriteria.Op.EQ);
ListByAffinityGroupId.done();
ZoneByDomainIdsSearch = createSearchBuilder();
ZoneByDomainIdsSearch.and("zoneId", ZoneByDomainIdsSearch.entity().getDataCenterId(), SearchCriteria.Op.NNULL);
ZoneByDomainIdsSearch.and("domainId", ZoneByDomainIdsSearch.entity().getDomainId(), SearchCriteria.Op.NIN);
@ -225,11 +234,15 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedZones(Long dataCenterId, Long domainId, Long accountId){
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedZones(Long dataCenterId, Long domainId,
Long accountId, Long affinityGroupId) {
SearchCriteria<DedicatedResourceVO> sc = ListAllZonesSearch.create();
if (dataCenterId != null) {
sc.setParameters("zoneId", dataCenterId);
}
if (affinityGroupId != null) {
sc.setParameters("affinityGroupId", affinityGroupId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
@ -241,11 +254,15 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
return searchAndCount(sc, null);
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedPods(Long podId, Long domainId, Long accountId){
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedPods(Long podId, Long domainId, Long accountId,
Long affinityGroupId) {
SearchCriteria<DedicatedResourceVO> sc = ListAllPodsSearch.create();
if (podId != null) {
sc.setParameters("podId", podId);
}
if (affinityGroupId != null) {
sc.setParameters("affinityGroupId", affinityGroupId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
@ -258,11 +275,16 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedClusters(Long clusterId, Long domainId, Long accountId){
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedClusters(Long clusterId, Long domainId,
Long accountId, Long affinityGroupId) {
SearchCriteria<DedicatedResourceVO> sc = ListAllClustersSearch.create();
if (clusterId != null) {
sc.setParameters("clusterId", clusterId);
}
if (affinityGroupId != null) {
sc.setParameters("affinityGroupId", affinityGroupId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
@ -275,11 +297,14 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
}
@Override
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedHosts(Long hostId, Long domainId, Long accountId){
public Pair<List<DedicatedResourceVO>, Integer> searchDedicatedHosts(Long hostId, Long domainId, Long accountId, Long affinityGroupId){
SearchCriteria<DedicatedResourceVO> sc = ListAllHostsSearch.create();
if (hostId != null) {
sc.setParameters("hostId", hostId);
}
if (affinityGroupId != null) {
sc.setParameters("affinityGroupId", affinityGroupId);
}
if(domainId != null) {
sc.setParameters("domainId", domainId);
if(accountId != null) {
@ -341,4 +366,11 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
SearchCriteria<Long> sc = ListHostsSearch.create();
return customSearch(sc, null);
}
@Override
public List<DedicatedResourceVO> listByAffinityGroupId(Long affinityGroupId) {
SearchCriteria<DedicatedResourceVO> sc = ListByAffinityGroupId.create();
sc.setParameters("affinityGroupId", affinityGroupId);
return listBy(sc);
}
}

View File

@ -30,6 +30,7 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
import org.apache.cloudstack.affinity.AffinityGroupVO;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
@ -66,6 +67,7 @@ import com.cloud.deploy.dao.PlannerHostReservationDao;
import com.cloud.exception.AffinityConflictException;
import com.cloud.exception.ConnectionException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
@ -133,6 +135,8 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
@Inject
protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
@Inject
AffinityGroupService _affinityGroupService;
@Inject
DataCenterDao _dcDao;
@Inject
PlannerHostReservationDao _plannerHostReserveDao;
@ -215,7 +219,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
}
}
checkForNonDedicatedResources(vmProfile, dc, avoids);
if (vm.getType() == VirtualMachine.Type.User) {
checkForNonDedicatedResources(vmProfile, dc, avoids);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: "
+ avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid());
@ -444,20 +450,48 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) {
boolean isExplicit = false;
VirtualMachine vm = vmProfile.getVirtualMachine();
// check affinity group of type Explicit dedication exists
VirtualMachine vm = vmProfile.getVirtualMachine();
// check if zone is dedicated. if yes check if vm owner has acess to it.
DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId());
if (dedicatedZone != null) {
long accountDomainId = vmProfile.getOwner().getDomainId();
long accountId = vmProfile.getOwner().getAccountId();
// If a zone is dedicated to an account then all hosts in this zone
// will be explicitly dedicated to
// that account. So there won't be any shared hosts in the zone, the
// only way to deploy vms from that
// account will be to use explicit dedication affinity group.
if (dedicatedZone.getAccountId() != null) {
if (dedicatedZone.getAccountId().equals(accountId)) {
return;
} else {
throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName()
+ " not available for the user account " + vmProfile.getOwner());
}
}
// if zone is dedicated to a domain. Check owner's access to the
// domain level dedication group
if (!_affinityGroupService.isAffinityGroupAvailableInDomain(dedicatedZone.getAffinityGroupId(),
accountDomainId)) {
throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName()
+ " not available for the user domain " + vmProfile.getOwner());
}
}
// check affinity group of type Explicit dedication exists. If No put
// dedicated pod/cluster/host in avoid list
List<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication");
if (vmGroupMappings != null && !vmGroupMappings.isEmpty()){
isExplicit = true;
}
if (!isExplicit && vm.getType() == VirtualMachine.Type.User) {
if (!isExplicit) {
//add explicitly dedicated resources in avoidList
DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId());
if (dedicatedZone != null && dedicatedZone.getDomainId() != null) {
throw new CloudRuntimeException("Failed to deploy VM. Zone " + dc.getName() + " is dedicated . Please use Explicit Dedication Affinity Group");
}
List<Long> allPodsInDc = _podDao.listAllPods(dc.getId());
List<Long> allDedicatedPods = _dedicatedDao.listAllPods();

View File

@ -2503,20 +2503,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
+ zone.getId());
}
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) {
if (dedicatedZone != null) {
DomainVO domain = _domainDao.findById(dedicatedZone.getDomainId());
if (domain == null) {
throw new CloudRuntimeException("Unable to find the domain "

View File

@ -140,6 +140,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
ControlledEntity.ACLType aclType = null;
Account owner = null;
boolean domainLevel = false;
if (account != null && domainId != null) {
@ -166,6 +167,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
// domain level group, owner is SYSTEM.
owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
aclType = ControlledEntity.ACLType.Domain;
domainLevel = true;
} else {
owner = caller;
@ -176,6 +178,10 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
throw new InvalidParameterValueException("Unable to create affinity group, a group with name "
+ affinityGroupName + " already exisits.");
}
if (domainLevel && _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName) != null) {
throw new InvalidParameterValueException("Unable to create affinity group, a group with name "
+ affinityGroupName + " already exisits under the domain.");
}
Transaction txn = Transaction.currentTxn();
txn.start();
@ -185,7 +191,9 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
_affinityGroupDao.persist(group);
if (domainId != null && aclType == ACLType.Domain) {
AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, false);
boolean subDomainAccess = false;
subDomainAccess = processor.subDomainAccess();
AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, subDomainAccess);
_affinityGroupDomainMapDao.persist(domainMap);
}
@ -251,6 +259,12 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
_affinityGroupVMMapDao.remove(sc);
}
// call processor to handle the group delete
AffinityGroupProcessor processor = getAffinityGroupProcessorForType(group.getType());
if (processor != null) {
processor.handleDeleteGroup(group);
}
_affinityGroupDao.expunge(affinityGroupId);
txn.commit();
@ -324,8 +338,9 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
if (componentMap.size() > 0) {
for (Entry<String, AffinityGroupProcessor> entry : componentMap.entrySet()) {
AffinityGroupProcessor processor = entry.getValue();
if (processor.isAdminControlledGroup() && !_accountMgr.isRootAdmin(caller.getType())) {
continue;
if (processor.isAdminControlledGroup()) {
continue; // we dont list the type if this group can be
// created only as an admin/system operation.
}
types.add(processor.getType());
}
@ -469,6 +484,15 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
return false;
}
private AffinityGroupProcessor getAffinityGroupProcessorForType(String affinityGroupType) {
for (AffinityGroupProcessor processor : _affinityProcessors) {
if (affinityGroupType != null && affinityGroupType.equals(processor.getType())) {
return processor;
}
}
return null;
}
@Override
public boolean isAffinityGroupAvailableInDomain(long affinityGroupId, long domainId) {
Long groupDomainId = null;

View File

@ -447,6 +447,7 @@ CREATE TABLE `cloud`.`dedicated_resources` (
`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',
`affinity_group_id` bigint unsigned NOT NULL COMMENT 'affinity group id associated',
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`),
@ -454,8 +455,10 @@ CREATE TABLE `cloud`.`dedicated_resources` (
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`),
CONSTRAINT `fk_dedicated_resources__affinity_group_id` FOREIGN KEY (`affinity_group_id`) REFERENCES `affinity_group`(`id`) ON DELETE CASCADE,
INDEX `i_dedicated_resources_domain_id`(`domain_id`),
INDEX `i_dedicated_resources_account_id`(`account_id`),
INDEX `i_dedicated_resources_affinity_group_id`(`affinity_group_id`),
CONSTRAINT `uc_dedicated_resources__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@ -486,9 +489,6 @@ 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