7070import com .cloud .utils .db .TransactionLegacy ;
7171import com .cloud .utils .db .UpdateBuilder ;
7272import com .cloud .utils .exception .CloudRuntimeException ;
73+ import java .util .Arrays ;
7374
7475@ DB
7576@ TableGenerator (name = "host_req_sq" , table = "op_host" , pkColumnName = "id" , valueColumnName = "sequence" , allocationSize = 1 )
@@ -78,12 +79,19 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
7879 private static final Logger status_logger = Logger .getLogger (Status .class );
7980 private static final Logger state_logger = Logger .getLogger (ResourceState .class );
8081
82+ private static final String LIST_HOST_IDS_BY_COMPUTETAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
83+ + "FROM (SELECT host_id, tag FROM host_tags GROUP BY host_id,tag) AS filtered "
84+ + "WHERE tag IN(%s) "
85+ + "GROUP BY host_id "
86+ + "HAVING tag_count = %s " ;
87+ private static final String SEPARATOR = "," ;
8188 private static final String LIST_CLUSTERID_FOR_HOST_TAG = "select distinct cluster_id from host join host_tags on host.id = host_tags.host_id and host_tags.tag = ?" ;
8289 private static final String GET_HOSTS_OF_ACTIVE_VMS = "select h.id " +
8390 "from vm_instance vm " +
8491 "join host h on (vm.host_id=h.id) " +
8592 "where vm.service_offering_id= ? and vm.state not in (\" Destroyed\" , \" Expunging\" , \" Error\" ) group by h.id" ;
8693
94+
8795 protected SearchBuilder <HostVO > TypePodDcStatusSearch ;
8896
8997 protected SearchBuilder <HostVO > IdStatusSearch ;
@@ -736,11 +744,6 @@ public void markHostsAsDisconnected(long msId, long lastPing) {
736744
737745 @ Override
738746 public List <HostVO > listByHostTag (Host .Type type , Long clusterId , Long podId , long dcId , String hostTag ) {
739-
740- SearchBuilder <HostTagVO > hostTagSearch = _hostTagsDao .createSearchBuilder ();
741- HostTagVO tagEntity = hostTagSearch .entity ();
742- hostTagSearch .and ("tag" , tagEntity .getTag (), SearchCriteria .Op .EQ );
743-
744747 SearchBuilder <HostVO > hostSearch = createSearchBuilder ();
745748 HostVO entity = hostSearch .entity ();
746749 hostSearch .and ("type" , entity .getType (), SearchCriteria .Op .EQ );
@@ -749,10 +752,8 @@ public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, lo
749752 hostSearch .and ("cluster" , entity .getClusterId (), SearchCriteria .Op .EQ );
750753 hostSearch .and ("status" , entity .getStatus (), SearchCriteria .Op .EQ );
751754 hostSearch .and ("resourceState" , entity .getResourceState (), SearchCriteria .Op .EQ );
752- hostSearch .join ("hostTagSearch" , hostTagSearch , entity .getId (), tagEntity .getHostId (), JoinBuilder .JoinType .INNER );
753755
754756 SearchCriteria <HostVO > sc = hostSearch .create ();
755- sc .setJoinParameters ("hostTagSearch" , "tag" , hostTag );
756757 sc .setParameters ("type" , type .toString ());
757758 if (podId != null ) {
758759 sc .setParameters ("pod" , podId );
@@ -764,7 +765,13 @@ public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, lo
764765 sc .setParameters ("status" , Status .Up .toString ());
765766 sc .setParameters ("resourceState" , ResourceState .Enabled .toString ());
766767
767- return listBy (sc );
768+ List <HostVO > tmpHosts = listBy (sc );
769+ List <HostVO > correctHostsByHostTags = new ArrayList ();
770+ List <Long > hostIdsByComputeOffTags = findHostByComputeOfferings (hostTag );
771+
772+ tmpHosts .forEach ((host ) -> { if (hostIdsByComputeOffTags .contains (host .getId ())) correctHostsByHostTags .add (host );});
773+
774+ return correctHostsByHostTags ;
768775 }
769776
770777 @ Override
@@ -1179,28 +1186,69 @@ public List<HostVO> listAllHostsByZoneAndHypervisorType(long zoneId, HypervisorT
11791186 }
11801187
11811188 @ Override
1182- public List <Long > listClustersByHostTag (String hostTagOnOffering ) {
1189+ public List <Long > listClustersByHostTag (String computeOfferingTags ) {
11831190 TransactionLegacy txn = TransactionLegacy .currentTxn ();
1191+ String sql = this .LIST_CLUSTERID_FOR_HOST_TAG ;
11841192 PreparedStatement pstmt = null ;
1185- List <Long > result = new ArrayList <Long >();
1186- StringBuilder sql = new StringBuilder (LIST_CLUSTERID_FOR_HOST_TAG );
1187- // during listing the clusters that cross the threshold
1188- // we need to check with disabled thresholds of each cluster if not defined at cluster consider the global value
1193+ List <Long > result = new ArrayList ();
1194+ List <String > tags = Arrays .asList (computeOfferingTags .split (this .SEPARATOR ));
1195+ String subselect = getHostIdsByComputeTags (tags );
1196+ sql = String .format (sql , subselect );
1197+
11891198 try {
1190- pstmt = txn .prepareAutoCloseStatement (sql .toString ());
1191- pstmt .setString (1 , hostTagOnOffering );
1199+ pstmt = txn .prepareStatement (sql );
1200+
1201+ for (int i = 0 ; i < tags .size (); i ++){
1202+ pstmt .setString (i +1 , tags .get (i ));
1203+ }
1204+
11921205 ResultSet rs = pstmt .executeQuery ();
11931206 while (rs .next ()) {
11941207 result .add (rs .getLong (1 ));
11951208 }
1209+ pstmt .close ();
1210+ if (result .isEmpty ()){
1211+ throw new CloudRuntimeException ("No suitable host found for follow compute offering tags: " + computeOfferingTags );
1212+ }
11961213 return result ;
11971214 } catch (SQLException e ) {
11981215 throw new CloudRuntimeException ("DB Exception on: " + sql , e );
1199- } catch (Throwable e ) {
1200- throw new CloudRuntimeException ("Caught: " + sql , e );
12011216 }
12021217 }
12031218
1219+ private List <Long > findHostByComputeOfferings (String computeOfferingTags ){
1220+ TransactionLegacy txn = TransactionLegacy .currentTxn ();
1221+ PreparedStatement pstmt = null ;
1222+ List <Long > result = new ArrayList ();
1223+ List <String > tags = Arrays .asList (computeOfferingTags .split (this .SEPARATOR ));
1224+ String select = getHostIdsByComputeTags (tags );
1225+ try {
1226+ pstmt = txn .prepareStatement (select );
1227+
1228+ for (int i = 0 ; i < tags .size (); i ++){
1229+ pstmt .setString (i +1 , tags .get (i ));
1230+ }
1231+
1232+ ResultSet rs = pstmt .executeQuery ();
1233+ while (rs .next ()) {
1234+ result .add (rs .getLong (1 ));
1235+ }
1236+ pstmt .close ();
1237+ if (result .isEmpty ()){
1238+ throw new CloudRuntimeException ("No suitable host found for follow compute offering tags: " + computeOfferingTags );
1239+ }
1240+ return result ;
1241+ } catch (SQLException e ) {
1242+ throw new CloudRuntimeException ("DB Exception on: " + select , e );
1243+ }
1244+ }
1245+
1246+ private String getHostIdsByComputeTags (List <String > offeringTags ){
1247+ List <String > questionMarks = new ArrayList ();
1248+ offeringTags .forEach ((tag ) -> { questionMarks .add ("?" ); });
1249+ return String .format (this .LIST_HOST_IDS_BY_COMPUTETAGS , String .join ("," , questionMarks ),questionMarks .size ());
1250+ }
1251+
12041252 @ Override
12051253 public List <HostVO > listHostsWithActiveVMs (long offeringId ) {
12061254 TransactionLegacy txn = TransactionLegacy .currentTxn ();
0 commit comments