cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From prachida...@apache.org
Subject [3/4] git commit: updated refs/heads/4.2 to b0947c9
Date Sat, 10 Aug 2013 18:19:45 GMT
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.


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

Branch: refs/heads/4.2
Commit: fac54d2334fa570e095238b1e05e81aa37aac7be
Parents: b965032
Author: Prachi Damle <prachi@cloud.com>
Authored: Fri Aug 9 14:11:44 2013 -0700
Committer: Prachi Damle <prachi@cloud.com>
Committed: Sat Aug 10 11:02:57 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/dc/DedicatedResources.java    |   2 +-
 .../affinity/AffinityGroupProcessor.java        |  13 +-
 .../affinity/AffinityProcessorBase.java         |  11 +
 .../com/cloud/upgrade/dao/Upgrade412to420.java  | 125 +++++++-
 .../affinity/dao/AffinityGroupDao.java          |  10 +-
 .../affinity/dao/AffinityGroupDaoImpl.java      |  66 ++++-
 .../affinity/ExplicitDedicationProcessor.java   | 296 +++++++++++--------
 .../api/commands/ListDedicatedClustersCmd.java  |   9 +
 .../api/commands/ListDedicatedHostsCmd.java     |   9 +
 .../api/commands/ListDedicatedPodsCmd.java      |   9 +
 .../api/commands/ListDedicatedZonesCmd.java     |   9 +
 .../api/response/DedicateClusterResponse.java   |  14 +
 .../api/response/DedicateHostResponse.java      |  12 +
 .../api/response/DedicatePodResponse.java       |  12 +
 .../api/response/DedicateZoneResponse.java      |  11 +
 .../dedicated/DedicatedResourceManagerImpl.java | 122 +++++++-
 .../dedicated/manager/DedicatedApiUnitTest.java |  20 +-
 .../cloud/acl/AffinityGroupAccessChecker.java   |   2 +
 .../configuration/ConfigurationManagerImpl.java |  43 ++-
 .../src/com/cloud/dc/DedicatedResourceVO.java   |  11 +-
 .../com/cloud/dc/dao/DedicatedResourceDao.java  |  11 +-
 .../cloud/dc/dao/DedicatedResourceDaoImpl.java  |  42 ++-
 .../deploy/DeploymentPlanningManagerImpl.java   |  50 +++-
 server/src/com/cloud/vm/UserVmManagerImpl.java  |  13 +-
 .../affinity/AffinityGroupServiceImpl.java      |  30 +-
 setup/db/db/schema-412to420.sql                 |   6 +-
 26 files changed, 781 insertions(+), 177 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/api/src/com/cloud/dc/DedicatedResources.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/dc/DedicatedResources.java b/api/src/com/cloud/dc/DedicatedResources.java
index e8e5ab3..b3aea50 100755
--- a/api/src/com/cloud/dc/DedicatedResources.java
+++ b/api/src/com/cloud/dc/DedicatedResources.java
@@ -29,5 +29,5 @@ public interface DedicatedResources extends InfrastructureEntity, InternalIdenti
     Long getDomainId();
     Long getAccountId();
     String getUuid();
-
+    long getAffinityGroupId();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java b/api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java
index 09a4a31..c93fff9 100644
--- a/api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java
+++ b/api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java
@@ -73,9 +73,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);
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java b/api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java
index c249f62..8ffdc9e 100644
--- a/api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java
+++ b/api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java
@@ -58,4 +58,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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/engine/schema/src/com/cloud/upgrade/dao/Upgrade412to420.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade412to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade412to420.java
index 501633a..e64aff4 100644
--- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade412to420.java
+++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade412to420.java
@@ -70,8 +70,9 @@ public class Upgrade412to420 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);
         createPlaceHolderNics(conn);
@@ -105,6 +106,126 @@ public class Upgrade412to420 implements DbUpgrade {
         migrateDatafromIsoIdInVolumesTable(conn);
     }
 
+    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");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java
index 296e7b1..6310a2f 100644
--- a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java
+++ b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java
@@ -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);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java
index d189d60..0be0088 100644
--- a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java
@@ -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);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java b/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
index 3806ae1..203eb34 100644
--- a/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
+++ b/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
@@ -43,6 +43,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;
@@ -87,161 +90,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 (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 (hostToUse.isEmpty() && !canUse) {
-                        throw new CloudRuntimeException("Cannot use this cluster " + cluster.getName() + " for explicit dedication");
+                }
+            }
+            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;
                     }
 
-                    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());
+                    // 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);
                             }
                         }
                     }
 
-                } 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 (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());
                     }
+                }
+            }
 
-                    if (hostsToUse.isEmpty() && clustersToUse.isEmpty() && !canUse) {
-                        throw new CloudRuntimeException("Cannot use this pod " + pod.getName() + " for explicit dedication");
+        } 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;
                     }
 
-                    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());
+                    // 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 (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());
+                        if (resource.getHostId() != null) {
+                            HostVO dHost = _hostDao.findById(resource.getHostId());
+                            if (dHost.getPodId() == pod.getId()) {
+                                hostsToUse.add(dHost);
                             }
                         }
                     }
 
-                } 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 (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 (s_logger.isDebugEnabled()) {
-                        s_logger.debug("ExplicitDedicationProcessor returns Avoid List as: Deploy avoids pods: " + avoid.getPodsToAvoid() + ", clusters: "
-                                + avoid.getClustersToAvoid() + ", hosts: " + avoid.getHostsToAvoid());
+            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) {
@@ -389,4 +404,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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
index f394787..613f2e7 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
@@ -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///////////////////
     /////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
index 736251b..5b1a410 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
@@ -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
     /////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
index da59eda..6f16d65 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
@@ -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///////////////////
     /////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
index a21f129..1fc1a19 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
@@ -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///////////////////
     /////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java
index 3c8dde3..e45938c 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java
index cea31fe..83126a2 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java
index 4bcaa61..3705666 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java
index 57497cd..ee067ed 100644
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
index c321b22..6afbbad 100755
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
@@ -25,6 +25,11 @@ import javax.inject.Inject;
 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;
@@ -92,6 +97,10 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
     @Inject AccountManager _accountMgr;
     @Inject UserVmDao _userVmDao;
     @Inject ConfigurationDao _configDao;
+    @Inject AffinityGroupDao _affinityGroupDao;
+
+    @Inject
+    AffinityGroupService _affinityGroupService;
 
     private int capacityReleaseInterval;
 
@@ -212,7 +221,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) {
@@ -329,7 +346,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) {
@@ -432,7 +456,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) {
@@ -520,7 +551,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) {
@@ -538,6 +576,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);
@@ -620,10 +697,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());
         }
@@ -637,10 +716,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());
         }
@@ -654,10 +735,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());
         }
@@ -671,10 +754,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());
         }
@@ -706,6 +791,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);
@@ -716,7 +803,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());
     }
 
@@ -726,6 +814,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);
@@ -736,7 +826,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());
     }
 
@@ -746,6 +837,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);
@@ -756,7 +849,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());
     }
 
@@ -765,6 +859,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) {
@@ -777,7 +873,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());
     }
 
@@ -809,6 +905,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;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
----------------------------------------------------------------------
diff --git a/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java b/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
index 58aae23..66f9d5f 100644
--- a/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
+++ b/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
@@ -28,6 +28,8 @@ import javax.naming.ConfigurationException;
 
 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;
@@ -208,28 +210,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);
     }
@@ -306,6 +308,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 {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/server/src/com/cloud/acl/AffinityGroupAccessChecker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/acl/AffinityGroupAccessChecker.java b/server/src/com/cloud/acl/AffinityGroupAccessChecker.java
index fcebf2f..bc1e631 100644
--- a/server/src/com/cloud/acl/AffinityGroupAccessChecker.java
+++ b/server/src/com/cloud/acl/AffinityGroupAccessChecker.java
@@ -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;
                 }
 
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 59a6742..b9b0b28 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -40,6 +40,9 @@ 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.ldap.LDAPConfigCmd;
@@ -298,6 +301,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
     public ManagementService _mgr;
     @Inject
     DedicatedResourceDao _dedicatedDao;
+    @Inject
+    AffinityGroupDao _affinityGroupDao;
+    @Inject
+    AffinityGroupService _affinityGroupService;
 
     // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
     @Inject
@@ -1968,8 +1975,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);
             }
 
@@ -1986,6 +1995,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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/server/src/com/cloud/dc/DedicatedResourceVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/dc/DedicatedResourceVO.java b/server/src/com/cloud/dc/DedicatedResourceVO.java
index a4c88f5..f1ec6a1 100644
--- a/server/src/com/cloud/dc/DedicatedResourceVO.java
+++ b/server/src/com/cloud/dc/DedicatedResourceVO.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/server/src/com/cloud/dc/dao/DedicatedResourceDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/dc/dao/DedicatedResourceDao.java b/server/src/com/cloud/dc/dao/DedicatedResourceDao.java
index 2eef83a..865e083 100644
--- a/server/src/com/cloud/dc/dao/DedicatedResourceDao.java
+++ b/server/src/com/cloud/dc/dao/DedicatedResourceDao.java
@@ -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);
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fac54d23/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java b/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
index c510860..6c91ce7 100644
--- a/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
+++ b/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
@@ -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("dataCenterId", 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);
+    }
 }


Mime
View raw message