diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index ea0bad98868..699fd6bd63f 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -222,6 +222,7 @@ + @@ -259,7 +260,6 @@ - diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java index 59c338e2803..a3cb76fe123 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java @@ -114,4 +114,6 @@ public interface PrimaryDataStoreDao extends GenericDao { List findZoneWideStoragePoolsByTags(long dcId, String[] tags); List findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType); + + List findLocalStoragePoolsByHostAndTags(long hostId, String[] tags); } diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index d35aa440f74..eea07628af8 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -24,19 +24,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.annotation.PostConstruct; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.springframework.stereotype.Component; - import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.ScopeType; +import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -45,7 +47,6 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; - @Local(value = { PrimaryDataStoreDao.class }) @DB() public class PrimaryDataStoreDaoImpl extends GenericDaoBase implements PrimaryDataStoreDao { @@ -54,8 +55,12 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase protected final SearchBuilder DcPodAnyClusterSearch; protected final SearchBuilder DeleteLvmSearch; protected final GenericSearchBuilder StatusCountSearch; + protected SearchBuilder HostSearch; + protected SearchBuilder HostPoolSearch; + protected SearchBuilder TagPoolSearch; @Inject protected StoragePoolDetailsDao _detailsDao; + @Inject protected StoragePoolHostDao _hostDao; private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and ("; private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; @@ -112,6 +117,26 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase } + @PostConstruct + void init() { + HostSearch = createSearchBuilder(); + TagPoolSearch = _detailsDao.createSearchBuilder(); + HostPoolSearch = _hostDao.createSearchBuilder(); + // Search for pools on the host + HostPoolSearch.and("hostId", HostPoolSearch.entity().getHostId(), Op.EQ); + // Set criteria for pools + HostSearch.and("scope", HostSearch.entity().getScope(), Op.EQ); + HostSearch.and("removed", HostSearch.entity().getRemoved(), Op.NULL); + HostSearch.and("status", HostSearch.entity().getStatus(), Op.EQ); + HostSearch.join("hostJoin", HostPoolSearch, HostSearch.entity().getId(), HostPoolSearch.entity().getPoolId(), JoinBuilder.JoinType.INNER); + // Set criteria for tags + TagPoolSearch.and("name", TagPoolSearch.entity().getName(), Op.EQ); + TagPoolSearch.and("value", TagPoolSearch.entity().getValue(), Op.EQ); + + HostSearch.join("tagJoin", TagPoolSearch, HostSearch.entity().getId(), TagPoolSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + HostSearch.done(); + } + @Override public List findPoolByName(String name) { SearchCriteria sc = AllFieldSearch.create(); @@ -353,6 +378,23 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase } } + @Override + public List findLocalStoragePoolsByHostAndTags(long hostId, String[] tags) { + + SearchCriteria sc = HostSearch.create(); + sc.setJoinParameters("hostJoin", "hostId", hostId ); + sc.setParameters("scope", ScopeType.HOST.toString()); + sc.setParameters("status", Status.Up.toString()); + if (!(tags == null || tags.length == 0 )) { + Map details = tagsToDetails(tags); + for (Map.Entry detail : details.entrySet()) { + sc.setJoinParameters("tagJoin","name", detail.getKey()); + sc.setJoinParameters("tagJoin", "value", detail.getValue()); + } + } + return listBy(sc); + } + @Override @DB public List searchForStoragePoolDetails(long poolId, String value) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java index 1f61e8b948d..51ab0feb047 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java @@ -28,7 +28,6 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; - import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -73,14 +72,13 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator { if (!dskCh.useLocalStorage()) { return null; } - List suitablePools = new ArrayList(); // data disk and host identified from deploying vm (attach volume case) if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) { - List hostPools = _poolHostDao.listByHostId(plan.getHostId()); - for (StoragePoolHostVO hostPool : hostPools) { - StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId()); + List hostTagsPools = null; + hostTagsPools =_storagePoolDao.findLocalStoragePoolsByHostAndTags(plan.getHostId(), dskCh.getTags()); + for (StoragePoolVO pool : hostTagsPools) { if (pool != null && pool.isLocal()) { StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); if (filter(avoid, storagePool, dskCh, plan)) { diff --git a/server/test/resources/createNetworkOffering.xml b/server/test/resources/createNetworkOffering.xml index c6228dab707..6ae739309b9 100644 --- a/server/test/resources/createNetworkOffering.xml +++ b/server/test/resources/createNetworkOffering.xml @@ -46,4 +46,6 @@ + +