Skip to content

Commit 0d5047b

Browse files
Improve listing of HA and non-HA hosts when ha.tag setting is defined and hosts have multiple tags along with ha tag (#10240)
1 parent 27efc77 commit 0d5047b

File tree

3 files changed

+57
-42
lines changed

3 files changed

+57
-42
lines changed

engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.cloud.org.Managed;
6161
import com.cloud.resource.ResourceState;
6262
import com.cloud.utils.DateUtil;
63+
import com.cloud.utils.StringUtils;
6364
import com.cloud.utils.db.Attribute;
6465
import com.cloud.utils.db.DB;
6566
import com.cloud.utils.db.Filter;
@@ -83,13 +84,13 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
8384
private static final Logger status_logger = Logger.getLogger(Status.class);
8485
private static final Logger state_logger = Logger.getLogger(ResourceState.class);
8586

86-
private static final String LIST_HOST_IDS_BY_COMPUTETAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
87-
+ "FROM (SELECT host_id, tag, is_tag_a_rule FROM host_tags GROUP BY host_id,tag) AS filtered "
88-
+ "WHERE tag IN(%s) AND is_tag_a_rule = 0 "
87+
private static final String LIST_HOST_IDS_BY_HOST_TAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
88+
+ "FROM (SELECT host_id, tag, is_tag_a_rule FROM host_tags GROUP BY host_id,tag,is_tag_a_rule) AS filtered "
89+
+ "WHERE tag IN (%s) AND (is_tag_a_rule = 0 OR is_tag_a_rule IS NULL) "
8990
+ "GROUP BY host_id "
9091
+ "HAVING tag_count = %s ";
9192
private static final String SEPARATOR = ",";
92-
private static final String LIST_CLUSTERID_FOR_HOST_TAG = "select distinct cluster_id from host join ( %s ) AS selected_hosts ON host.id = selected_hosts.host_id";
93+
private static final String LIST_CLUSTER_IDS_FOR_HOST_TAGS = "select distinct cluster_id from host join ( %s ) AS selected_hosts ON host.id = selected_hosts.host_id";
9394
private static final String GET_HOSTS_OF_ACTIVE_VMS = "select h.id " +
9495
"from vm_instance vm " +
9596
"join host h on (vm.host_id=h.id) " +
@@ -785,6 +786,15 @@ public void markHostsAsDisconnected(long msId, long lastPing) {
785786

786787
@Override
787788
public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag) {
789+
return listHostsWithOrWithoutHostTags(type, clusterId, podId, dcId, hostTag, true);
790+
}
791+
792+
private List<HostVO> listHostsWithOrWithoutHostTags(Host.Type type, Long clusterId, Long podId, long dcId, String hostTags, boolean withHostTags) {
793+
if (StringUtils.isEmpty(hostTags)) {
794+
s_logger.debug("Host tags not specified, to list hosts");
795+
return new ArrayList();
796+
}
797+
788798
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
789799
HostVO entity = hostSearch.entity();
790800
hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
@@ -795,7 +805,9 @@ public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, lo
795805
hostSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ);
796806

797807
SearchCriteria<HostVO> sc = hostSearch.create();
798-
sc.setParameters("type", type.toString());
808+
if (type != null) {
809+
sc.setParameters("type", type.toString());
810+
}
799811
if (podId != null) {
800812
sc.setParameters("pod", podId);
801813
}
@@ -806,27 +818,38 @@ public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, lo
806818
sc.setParameters("status", Status.Up.toString());
807819
sc.setParameters("resourceState", ResourceState.Enabled.toString());
808820

809-
List<HostVO> tmpHosts = listBy(sc);
810-
List<HostVO> correctHostsByHostTags = new ArrayList();
811-
List<Long> hostIdsByComputeOffTags = findHostByComputeOfferings(hostTag);
821+
List<HostVO> upAndEnabledHosts = listBy(sc);
822+
if (CollectionUtils.isEmpty(upAndEnabledHosts)) {
823+
return new ArrayList();
824+
}
812825

813-
tmpHosts.forEach((host) -> { if(hostIdsByComputeOffTags.contains(host.getId())) correctHostsByHostTags.add(host);});
826+
List<Long> hostIdsByHostTags = findHostIdsByHostTags(hostTags);
827+
if (CollectionUtils.isEmpty(hostIdsByHostTags)) {
828+
return withHostTags ? new ArrayList() : upAndEnabledHosts;
829+
}
814830

815-
return correctHostsByHostTags;
831+
if (withHostTags) {
832+
List<HostVO> upAndEnabledHostsWithHostTags = new ArrayList();
833+
upAndEnabledHosts.forEach((host) -> { if (hostIdsByHostTags.contains(host.getId())) upAndEnabledHostsWithHostTags.add(host);});
834+
return upAndEnabledHostsWithHostTags;
835+
} else {
836+
List<HostVO> upAndEnabledHostsWithoutHostTags = new ArrayList();
837+
upAndEnabledHosts.forEach((host) -> { if (!hostIdsByHostTags.contains(host.getId())) upAndEnabledHostsWithoutHostTags.add(host);});
838+
return upAndEnabledHostsWithoutHostTags;
839+
}
816840
}
817841

818842
@Override
819843
public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag) {
844+
if (StringUtils.isNotEmpty(haTag)) {
845+
return listHostsWithOrWithoutHostTags(type, clusterId, podId, dcId, haTag, false);
846+
}
847+
820848
SearchBuilder<HostTagVO> hostTagSearch = _hostTagsDao.createSearchBuilder();
821849
hostTagSearch.and();
822850
hostTagSearch.op("isTagARule", hostTagSearch.entity().getIsTagARule(), Op.EQ);
823851
hostTagSearch.or("tagDoesNotExist", hostTagSearch.entity().getIsTagARule(), Op.NULL);
824852
hostTagSearch.cp();
825-
if (haTag != null && !haTag.isEmpty()) {
826-
hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
827-
hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
828-
hostTagSearch.cp();
829-
}
830853

831854
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
832855

@@ -837,18 +860,12 @@ public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Lon
837860
hostSearch.and("status", hostSearch.entity().getStatus(), SearchCriteria.Op.EQ);
838861
hostSearch.and("resourceState", hostSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
839862

840-
841863
hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
842864

843-
844865
SearchCriteria<HostVO> sc = hostSearch.create();
845866

846867
sc.setJoinParameters("hostTagSearch", "isTagARule", false);
847868

848-
if (haTag != null && !haTag.isEmpty()) {
849-
sc.setJoinParameters("hostTagSearch", "tag", haTag);
850-
}
851-
852869
if (type != null) {
853870
sc.setParameters("type", type);
854871
}
@@ -1300,19 +1317,19 @@ public List<HostVO> listAllHostsThatHaveNoRuleTag(Type type, Long clusterId, Lon
13001317
}
13011318

13021319
@Override
1303-
public List<Long> listClustersByHostTag(String computeOfferingTags) {
1320+
public List<Long> listClustersByHostTag(String hostTags) {
13041321
TransactionLegacy txn = TransactionLegacy.currentTxn();
1305-
String sql = this.LIST_CLUSTERID_FOR_HOST_TAG;
1322+
String selectStmtToListClusterIdsByHostTags = this.LIST_CLUSTER_IDS_FOR_HOST_TAGS;
13061323
PreparedStatement pstmt = null;
13071324
List<Long> result = new ArrayList();
1308-
List<String> tags = Arrays.asList(computeOfferingTags.split(this.SEPARATOR));
1309-
String subselect = getHostIdsByComputeTags(tags);
1310-
sql = String.format(sql, subselect);
1325+
List<String> tags = Arrays.asList(hostTags.split(this.SEPARATOR));
1326+
String selectStmtToListHostIdsByHostTags = getSelectStmtToListHostIdsByHostTags(tags);
1327+
selectStmtToListClusterIdsByHostTags = String.format(selectStmtToListClusterIdsByHostTags, selectStmtToListHostIdsByHostTags);
13111328

13121329
try {
1313-
pstmt = txn.prepareStatement(sql);
1330+
pstmt = txn.prepareStatement(selectStmtToListClusterIdsByHostTags);
13141331

1315-
for(int i = 0; i < tags.size(); i++){
1332+
for (int i = 0; i < tags.size(); i++){
13161333
pstmt.setString(i+1, tags.get(i));
13171334
}
13181335

@@ -1323,20 +1340,20 @@ public List<Long> listClustersByHostTag(String computeOfferingTags) {
13231340
pstmt.close();
13241341
return result;
13251342
} catch (SQLException e) {
1326-
throw new CloudRuntimeException("DB Exception on: " + sql, e);
1343+
throw new CloudRuntimeException("DB Exception on: " + selectStmtToListClusterIdsByHostTags, e);
13271344
}
13281345
}
13291346

1330-
private List<Long> findHostByComputeOfferings(String computeOfferingTags){
1347+
private List<Long> findHostIdsByHostTags(String hostTags){
13311348
TransactionLegacy txn = TransactionLegacy.currentTxn();
13321349
PreparedStatement pstmt = null;
13331350
List<Long> result = new ArrayList();
1334-
List<String> tags = Arrays.asList(computeOfferingTags.split(this.SEPARATOR));
1335-
String select = getHostIdsByComputeTags(tags);
1351+
List<String> tags = Arrays.asList(hostTags.split(this.SEPARATOR));
1352+
String selectStmtToListHostIdsByHostTags = getSelectStmtToListHostIdsByHostTags(tags);
13361353
try {
1337-
pstmt = txn.prepareStatement(select);
1354+
pstmt = txn.prepareStatement(selectStmtToListHostIdsByHostTags);
13381355

1339-
for(int i = 0; i < tags.size(); i++){
1356+
for (int i = 0; i < tags.size(); i++){
13401357
pstmt.setString(i+1, tags.get(i));
13411358
}
13421359

@@ -1347,7 +1364,7 @@ private List<Long> findHostByComputeOfferings(String computeOfferingTags){
13471364
pstmt.close();
13481365
return result;
13491366
} catch (SQLException e) {
1350-
throw new CloudRuntimeException("DB Exception on: " + select, e);
1367+
throw new CloudRuntimeException("DB Exception on: " + selectStmtToListHostIdsByHostTags, e);
13511368
}
13521369
}
13531370

@@ -1372,10 +1389,10 @@ public List<Long> findClustersThatMatchHostTagRule(String computeOfferingTags) {
13721389
return new ArrayList<>(result);
13731390
}
13741391

1375-
private String getHostIdsByComputeTags(List<String> offeringTags){
1392+
private String getSelectStmtToListHostIdsByHostTags(List<String> hostTags){
13761393
List<String> questionMarks = new ArrayList();
1377-
offeringTags.forEach((tag) -> { questionMarks.add("?"); });
1378-
return String.format(this.LIST_HOST_IDS_BY_COMPUTETAGS, String.join(",", questionMarks),questionMarks.size());
1394+
hostTags.forEach((tag) -> { questionMarks.add("?"); });
1395+
return String.format(this.LIST_HOST_IDS_BY_HOST_TAGS, String.join(",", questionMarks), questionMarks.size());
13791396
}
13801397

13811398
@Override

server/src/main/java/com/cloud/server/ManagementServerImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@ private Pair<List<HostVO>, Integer> searchForServers(final Long startIndex, fina
19191919

19201920
final String haTag = _haMgr.getHaTag();
19211921
SearchBuilder<HostTagVO> hostTagSearch = null;
1922-
if (haHosts != null && haTag != null && !haTag.isEmpty()) {
1922+
if (haHosts != null && StringUtils.isNotEmpty(haTag)) {
19231923
hostTagSearch = _hostTagsDao.createSearchBuilder();
19241924
if ((Boolean)haHosts) {
19251925
hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.EQ);
@@ -1980,7 +1980,7 @@ private Pair<List<HostVO>, Integer> searchForServers(final Long startIndex, fina
19801980
sc.setParameters("resourceState", resourceState);
19811981
}
19821982

1983-
if (haHosts != null && haTag != null && !haTag.isEmpty()) {
1983+
if (haHosts != null && StringUtils.isNotEmpty(haTag)) {
19841984
sc.setJoinParameters("hostTagSearch", "tag", haTag);
19851985
}
19861986

server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,6 @@ public void checkClusterListBasedOnHostTag() throws InsufficientServerCapacityEx
217217
}
218218

219219
private List<Long> initializeForClusterListBasedOnHostTag(ServiceOffering offering) {
220-
221-
222220
when(offering.getHostTag()).thenReturn("hosttag1");
223221
initializeForClusterThresholdDisabled();
224222
List<Long> matchingClusters = new ArrayList<>();

0 commit comments

Comments
 (0)