Skip to content

Commit ef22b42

Browse files
author
Prachi Damle
committed
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
1 parent a06bd9f commit ef22b42

26 files changed

Lines changed: 783 additions & 177 deletions

File tree

api/src/com/cloud/dc/DedicatedResources.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ public interface DedicatedResources extends InfrastructureEntity, InternalIdenti
2929
Long getDomainId();
3030
Long getAccountId();
3131
String getUuid();
32-
32+
long getAffinityGroupId();
3333
}

api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,20 @@ boolean check(VirtualMachineProfile vm, DeployDestination plannedDestination)
7272
* canBeSharedDomainWide() should return true if the affinity/anti-affinity
7373
* group can be created for a domain and shared by all accounts under the
7474
* domain.
75-
*
75+
*
7676
* @return boolean true/false
7777
*/
7878
boolean canBeSharedDomainWide();
7979

80+
/**
81+
* subDomainAccess() should return true if the affinity/anti-affinity group
82+
* can be created for a domain and used by the sub-domains. If true, all
83+
* accounts under the sub-domains can see this group and use it.
84+
*
85+
* @return boolean true/false
86+
*/
87+
boolean subDomainAccess();
88+
89+
void handleDeleteGroup(AffinityGroup group);
90+
8091
}

api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,15 @@ public boolean isAdminControlledGroup() {
5757
public boolean canBeSharedDomainWide() {
5858
return false;
5959
}
60+
61+
@Override
62+
public void handleDeleteGroup(AffinityGroup group) {
63+
// TODO Auto-generated method stub
64+
return;
65+
}
66+
67+
@Override
68+
public boolean subDomainAccess() {
69+
return false;
70+
}
6071
}

engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ public File[] getPrepareScripts() {
7575
return new File[] { new File(script) };
7676
}
7777

78-
@Override
79-
public void performDataMigration(Connection conn) {
78+
@Override
79+
public void performDataMigration(Connection conn) {
80+
movePrivateZoneToDedicatedResource(conn);
8081
upgradeVmwareLabels(conn);
8182
persistLegacyZones(conn);
8283
persistVswitchConfiguration(conn);
@@ -262,6 +263,126 @@ private void setConfigurationParameter(Connection conn, String category, String
262263
}
263264
}
264265

266+
private void movePrivateZoneToDedicatedResource(Connection conn) {
267+
268+
PreparedStatement pstmt = null;
269+
ResultSet rs = null;
270+
PreparedStatement pstmtUpdate = null;
271+
272+
try {
273+
pstmt = conn.prepareStatement("SELECT `id`, `domain_id` FROM `cloud`.`data_center` WHERE `domain_id` IS NOT NULL");
274+
rs = pstmt.executeQuery();
275+
276+
while (rs.next()) {
277+
long zoneId = rs.getLong(1);
278+
long domainId = rs.getLong(2);
279+
long affinityGroupId;
280+
281+
// create or find an affinity group for this domain of type
282+
// 'ExplicitDedication'
283+
284+
PreparedStatement pstmt2 = null;
285+
ResultSet rs2 = null;
286+
pstmt2 = conn
287+
.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 = ?)");
288+
pstmt2.setLong(1, domainId);
289+
rs2 = pstmt2.executeQuery();
290+
if (rs2.next()) {
291+
// group exists, use it
292+
affinityGroupId = rs2.getLong(1);
293+
dedicateZone(conn, zoneId, domainId, affinityGroupId);
294+
} else {
295+
// create new group
296+
rs2.close();
297+
pstmt2.close();
298+
299+
pstmt2 = conn.prepareStatement("SELECT name FROM `cloud`.`domain` where id = ?");
300+
pstmt2.setLong(1, domainId);
301+
rs2 = pstmt2.executeQuery();
302+
String domainName = "";
303+
if (rs2.next()) {
304+
// group exists, use it
305+
domainName = rs2.getString(1);
306+
}
307+
rs2.close();
308+
pstmt2.close();
309+
// create new domain level group for this domain
310+
String type = "ExplicitDedication";
311+
String uuid = UUID.randomUUID().toString();
312+
String groupName = "DedicatedGrp-domain-" + domainName;
313+
s_logger.debug("Adding AffinityGroup of type " + type + " for domain id " + domainId);
314+
315+
String sql = "INSERT INTO `cloud`.`affinity_group` (`name`, `type`, `uuid`, `description`, `domain_id`, `account_id`, `acl_type`) VALUES (?, ?, ?, ?, 1, 1, 'Domain')";
316+
pstmtUpdate = conn.prepareStatement(sql);
317+
pstmtUpdate.setString(1, groupName);
318+
pstmtUpdate.setString(2, type);
319+
pstmtUpdate.setString(3, uuid);
320+
pstmtUpdate.setString(4, "dedicated resources group");
321+
pstmtUpdate.executeUpdate();
322+
pstmtUpdate.close();
323+
324+
pstmt2 = conn
325+
.prepareStatement("SELECT affinity_group.id FROM `cloud`.`affinity_group` where uuid = ?");
326+
pstmt2.setString(1, uuid);
327+
rs2 = pstmt2.executeQuery();
328+
if (rs2.next()) {
329+
affinityGroupId = rs2.getLong(1);
330+
dedicateZone(conn, zoneId, domainId, affinityGroupId);
331+
}
332+
}
333+
rs2.close();
334+
pstmt2.close();
335+
}
336+
337+
} catch (SQLException e) {
338+
throw new CloudRuntimeException("Exception while Moving private zone information to dedicated resources", e);
339+
} finally {
340+
if (pstmtUpdate != null) {
341+
try {
342+
pstmtUpdate.close();
343+
} catch (SQLException e) {
344+
}
345+
}
346+
if (rs != null) {
347+
try {
348+
rs.close();
349+
} catch (SQLException e) {
350+
}
351+
}
352+
if (pstmt != null) {
353+
try {
354+
pstmt.close();
355+
} catch (SQLException e) {
356+
}
357+
}
358+
359+
}
360+
}
361+
362+
private void dedicateZone(Connection conn, long zoneId, long domainId, long affinityGroupId) {
363+
PreparedStatement pstmtUpdate2 = null;
364+
try {
365+
// create the dedicated resources entry
366+
String sql = "INSERT INTO `cloud`.`dedicated_resources` (`uuid`,`data_center_id`, `domain_id`, `affinity_group_id`) VALUES (?, ?, ?, ?)";
367+
pstmtUpdate2 = conn.prepareStatement(sql);
368+
pstmtUpdate2.setString(1, UUID.randomUUID().toString());
369+
pstmtUpdate2.setLong(2, zoneId);
370+
pstmtUpdate2.setLong(3, domainId);
371+
pstmtUpdate2.setLong(4, affinityGroupId);
372+
pstmtUpdate2.executeUpdate();
373+
pstmtUpdate2.close();
374+
} catch (SQLException e) {
375+
throw new CloudRuntimeException("Exception while saving zone to dedicated resources", e);
376+
} finally {
377+
if (pstmtUpdate2 != null) {
378+
try {
379+
pstmtUpdate2.close();
380+
} catch (SQLException e) {
381+
}
382+
}
383+
}
384+
}
385+
265386
private void fixBaremetalForeignKeys(Connection conn) {
266387
List<String> keys = new ArrayList<String>();
267388
keys.add("fk_external_dhcp_devices_nsp_id");

engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.List;
2020

21+
import org.apache.cloudstack.affinity.AffinityGroup;
2122
import org.apache.cloudstack.affinity.AffinityGroupVO;
2223
import com.cloud.utils.db.GenericDao;
2324

@@ -26,5 +27,12 @@ public interface AffinityGroupDao extends GenericDao<AffinityGroupVO, Long> {
2627
boolean isNameInUse(Long accountId, Long domainId, String name);
2728
AffinityGroupVO findByAccountAndName(Long accountId, String name);
2829
List<AffinityGroupVO> findByAccountAndNames(Long accountId, String... names);
29-
int removeByAccountId(long accountId);
30+
31+
int removeByAccountId(long accountId);
32+
33+
AffinityGroup findDomainLevelGroupByName(Long domainId, String affinityGroupName);
34+
35+
AffinityGroup findByAccountAndType(Long accountId, String string);
36+
37+
AffinityGroup findDomainLevelGroupByType(Long domainId, String string);
3038
}

engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,29 @@
2020

2121
import javax.annotation.PostConstruct;
2222
import javax.ejb.Local;
23+
import javax.inject.Inject;
24+
25+
import org.apache.cloudstack.acl.ControlledEntity;
26+
import org.apache.cloudstack.affinity.AffinityGroup;
27+
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
2328
import org.apache.cloudstack.affinity.AffinityGroupVO;
24-
import org.springframework.stereotype.Component;
29+
2530
import com.cloud.utils.db.GenericDaoBase;
2631
import com.cloud.utils.db.SearchBuilder;
2732
import com.cloud.utils.db.SearchCriteria;
33+
import com.cloud.utils.db.JoinBuilder.JoinType;
2834

2935
@Local(value = { AffinityGroupDao.class })
3036
public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long> implements AffinityGroupDao {
3137
private SearchBuilder<AffinityGroupVO> AccountIdSearch;
3238
private SearchBuilder<AffinityGroupVO> AccountIdNameSearch;
3339
private SearchBuilder<AffinityGroupVO> AccountIdNamesSearch;
34-
40+
private SearchBuilder<AffinityGroupVO> DomainLevelNameSearch;
41+
private SearchBuilder<AffinityGroupVO> AccountIdTypeSearch;
42+
@Inject
43+
AffinityGroupDomainMapDao _groupDomainDao;
44+
45+
private SearchBuilder<AffinityGroupVO> DomainLevelTypeSearch;
3546

3647
public AffinityGroupDaoImpl() {
3748

@@ -51,6 +62,30 @@ protected void init() {
5162
AccountIdNamesSearch.and("accountId", AccountIdNamesSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
5263
AccountIdNamesSearch.and("groupNames", AccountIdNamesSearch.entity().getName(), SearchCriteria.Op.IN);
5364
AccountIdNameSearch.done();
65+
66+
SearchBuilder<AffinityGroupDomainMapVO> domainMapSearch = _groupDomainDao.createSearchBuilder();
67+
domainMapSearch.and("domainId", domainMapSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
68+
69+
DomainLevelNameSearch = createSearchBuilder();
70+
DomainLevelNameSearch.and("name", DomainLevelNameSearch.entity().getName(), SearchCriteria.Op.EQ);
71+
DomainLevelNameSearch.and("aclType", DomainLevelNameSearch.entity().getAclType(), SearchCriteria.Op.EQ);
72+
DomainLevelNameSearch.join("domainMapSearch", domainMapSearch, domainMapSearch.entity().getAffinityGroupId(),
73+
DomainLevelNameSearch.entity().getId(), JoinType.INNER);
74+
DomainLevelNameSearch.done();
75+
76+
AccountIdTypeSearch = createSearchBuilder();
77+
AccountIdTypeSearch.and("accountId", AccountIdTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
78+
AccountIdTypeSearch.and("type", AccountIdTypeSearch.entity().getType(), SearchCriteria.Op.EQ);
79+
80+
SearchBuilder<AffinityGroupDomainMapVO> domainTypeSearch = _groupDomainDao.createSearchBuilder();
81+
domainTypeSearch.and("domainId", domainTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
82+
DomainLevelTypeSearch = createSearchBuilder();
83+
DomainLevelTypeSearch.and("type", DomainLevelTypeSearch.entity().getType(), SearchCriteria.Op.EQ);
84+
DomainLevelTypeSearch.and("aclType", DomainLevelTypeSearch.entity().getAclType(), SearchCriteria.Op.EQ);
85+
DomainLevelTypeSearch.join("domainTypeSearch", domainTypeSearch,
86+
domainTypeSearch.entity().getAffinityGroupId(),
87+
DomainLevelTypeSearch.entity().getId(), JoinType.INNER);
88+
DomainLevelTypeSearch.done();
5489
}
5590

5691
@Override
@@ -99,4 +134,31 @@ public int removeByAccountId(long accountId) {
99134
sc.setParameters("accountId", accountId);
100135
return expunge(sc);
101136
}
137+
138+
@Override
139+
public AffinityGroup findDomainLevelGroupByName(Long domainId, String affinityGroupName) {
140+
SearchCriteria<AffinityGroupVO> sc = DomainLevelNameSearch.create();
141+
sc.setParameters("aclType", ControlledEntity.ACLType.Domain);
142+
sc.setParameters("name", affinityGroupName);
143+
sc.setJoinParameters("domainMapSearch", "domainId", domainId);
144+
return findOneBy(sc);
145+
}
146+
147+
@Override
148+
public AffinityGroup findByAccountAndType(Long accountId, String type) {
149+
SearchCriteria<AffinityGroupVO> sc = AccountIdTypeSearch.create();
150+
sc.setParameters("accountId", accountId);
151+
sc.setParameters("type", type);
152+
153+
return findOneBy(sc);
154+
}
155+
156+
@Override
157+
public AffinityGroup findDomainLevelGroupByType(Long domainId, String type) {
158+
SearchCriteria<AffinityGroupVO> sc = DomainLevelTypeSearch.create();
159+
sc.setParameters("aclType", ControlledEntity.ACLType.Domain);
160+
sc.setParameters("type", type);
161+
sc.setJoinParameters("domainTypeSearch", "domainId", domainId);
162+
return findOneBy(sc);
163+
}
102164
}

0 commit comments

Comments
 (0)