You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by we...@apache.org on 2024/03/18 17:08:26 UTC
(cloudstack) branch 4.19 updated: Use join instead of views (#8321)
This is an automated email from the ASF dual-hosted git repository.
weizhou pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.19 by this push:
new 0043540fa30 Use join instead of views (#8321)
0043540fa30 is described below
commit 0043540fa301d2d817bcb30e2130f13ed85d797d
Author: Vishesh <vi...@gmail.com>
AuthorDate: Mon Mar 18 22:38:19 2024 +0530
Use join instead of views (#8321)
---
.../java/com/cloud/offering/ServiceOffering.java | 2 +-
.../org/apache/cloudstack/acl/RoleService.java | 4 +-
.../apache/cloudstack/api/InternalIdentity.java | 14 +
.../java/com/cloud/service/ServiceOfferingVO.java | 4 +-
.../org/apache/cloudstack/acl/dao/RoleDao.java | 2 +
.../org/apache/cloudstack/acl/dao/RoleDaoImpl.java | 17 +
.../resourcedetail/DiskOfferingDetailVO.java | 4 +
.../storage/datastore/db/ImageStoreDao.java | 2 +
.../storage/datastore/db/ImageStoreDaoImpl.java | 16 +
.../storage/datastore/db/PrimaryDataStoreDao.java | 8 +
.../datastore/db/PrimaryDataStoreDaoImpl.java | 98 ++
.../db/views/cloud.service_offering_view.sql | 2 +-
.../main/java/com/cloud/utils/db/Attribute.java | 9 +
.../main/java/com/cloud/utils/db/GenericDao.java | 2 +
.../java/com/cloud/utils/db/GenericDaoBase.java | 152 ++-
.../com/cloud/utils/db/GenericSearchBuilder.java | 22 +
.../main/java/com/cloud/utils/db/JoinBuilder.java | 62 +-
.../main/java/com/cloud/utils/db/SearchBase.java | 93 +-
.../java/com/cloud/utils/db/SearchCriteria.java | 12 +-
.../com/cloud/utils/db/GenericDaoBaseTest.java | 35 +-
.../cloudstack/metrics/MetricsServiceImpl.java | 9 +-
server/src/main/java/com/cloud/api/ApiDBUtils.java | 26 +
.../java/com/cloud/api/query/QueryManagerImpl.java | 1174 +++++++++++++-------
.../com/cloud/api/query/ViewResponseHelper.java | 6 +-
.../com/cloud/api/query/dao/AccountJoinDao.java | 2 +
.../cloud/api/query/dao/AccountJoinDaoImpl.java | 53 +
.../cloud/api/query/dao/DiskOfferingJoinDao.java | 2 +
.../api/query/dao/DiskOfferingJoinDaoImpl.java | 54 +
.../com/cloud/api/query/dao/DomainJoinDao.java | 2 +
.../com/cloud/api/query/dao/DomainJoinDaoImpl.java | 53 +
.../api/query/dao/ServiceOfferingJoinDao.java | 1 +
.../api/query/dao/ServiceOfferingJoinDaoImpl.java | 55 +-
.../cloud/api/query/dao/StoragePoolJoinDao.java | 5 -
.../api/query/dao/StoragePoolJoinDaoImpl.java | 74 --
.../cloud/api/query/dao/TemplateJoinDaoImpl.java | 11 +-
.../configuration/ConfigurationManagerImpl.java | 2 +-
.../java/com/cloud/network/NetworkServiceImpl.java | 4 +-
.../org/apache/cloudstack/acl/RoleManagerImpl.java | 27 +-
.../com/cloud/api/query/QueryManagerImplTest.java | 38 +-
.../com/cloud/network/NetworkServiceImplTest.java | 4 +-
.../java/com/cloud/user/MockUsageEventDao.java | 5 +
41 files changed, 1592 insertions(+), 575 deletions(-)
diff --git a/api/src/main/java/com/cloud/offering/ServiceOffering.java b/api/src/main/java/com/cloud/offering/ServiceOffering.java
index 278acbe231e..58c7b0dbaf9 100644
--- a/api/src/main/java/com/cloud/offering/ServiceOffering.java
+++ b/api/src/main/java/com/cloud/offering/ServiceOffering.java
@@ -102,7 +102,7 @@ public interface ServiceOffering extends InfrastructureEntity, InternalIdentity,
boolean getDefaultUse();
- String getSystemVmType();
+ String getVmType();
String getDeploymentPlanner();
diff --git a/api/src/main/java/org/apache/cloudstack/acl/RoleService.java b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
index 9becce643d4..07f62a7e7f8 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
@@ -38,7 +38,9 @@ public interface RoleService {
* Moreover, we will check if the requested role is of 'Admin' type; roles with 'Admin' type should only be visible to 'root admins'.
* Therefore, if a non-'root admin' user tries to search for an 'Admin' role, this method will return null.
*/
- Role findRole(Long id, boolean removePrivateRoles);
+ Role findRole(Long id, boolean ignorePrivateRoles);
+
+ List<Role> findRoles(List<Long> ids, boolean ignorePrivateRoles);
Role findRole(Long id);
diff --git a/api/src/main/java/org/apache/cloudstack/api/InternalIdentity.java b/api/src/main/java/org/apache/cloudstack/api/InternalIdentity.java
index 4149dd1c846..ce214e05b4f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/InternalIdentity.java
+++ b/api/src/main/java/org/apache/cloudstack/api/InternalIdentity.java
@@ -25,4 +25,18 @@ import java.io.Serializable;
public interface InternalIdentity extends Serializable {
long getId();
+
+ /*
+ Helper method to add conditions in joins where some column name is equal to a string value
+ */
+ default Object setString(String str) {
+ return null;
+ }
+
+ /*
+ Helper method to add conditions in joins where some column name is equal to a long value
+ */
+ default Object setLong(Long l) {
+ return null;
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java
index 31e4b073c13..7f5c1a7afa1 100644
--- a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java
+++ b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java
@@ -194,7 +194,7 @@ public class ServiceOfferingVO implements ServiceOffering {
limitCpuUse = offering.getLimitCpuUse();
volatileVm = offering.isVolatileVm();
hostTag = offering.getHostTag();
- vmType = offering.getSystemVmType();
+ vmType = offering.getVmType();
systemUse = offering.isSystemUse();
dynamicScalingEnabled = offering.isDynamicScalingEnabled();
diskOfferingStrictness = offering.diskOfferingStrictness;
@@ -278,7 +278,7 @@ public class ServiceOfferingVO implements ServiceOffering {
}
@Override
- public String getSystemVmType() {
+ public String getVmType() {
return vmType;
}
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDao.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDao.java
index a776f7b6fe6..2d4151afc7d 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDao.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDao.java
@@ -37,4 +37,6 @@ public interface RoleDao extends GenericDao<RoleVO, Long> {
Pair<List<RoleVO>, Integer> findAllByRoleType(RoleType type, Long offset, Long limit, boolean showPrivateRole);
Pair<List<RoleVO>, Integer> listAllRoles(Long startIndex, Long limit, boolean showPrivateRole);
+
+ List<RoleVO> searchByIds(Long... ids);
}
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDaoImpl.java
index 06d3108076a..2e8fdd5fcc2 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDaoImpl.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDaoImpl.java
@@ -28,10 +28,13 @@ import org.apache.cloudstack.acl.RoleVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
+import java.util.Collections;
import java.util.List;
@Component
public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao {
+
+ private final SearchBuilder<RoleVO> RoleByIdsSearch;
private final SearchBuilder<RoleVO> RoleByNameSearch;
private final SearchBuilder<RoleVO> RoleByTypeSearch;
private final SearchBuilder<RoleVO> RoleByNameAndTypeSearch;
@@ -40,6 +43,10 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
public RoleDaoImpl() {
super();
+ RoleByIdsSearch = createSearchBuilder();
+ RoleByIdsSearch.and("idIN", RoleByIdsSearch.entity().getId(), SearchCriteria.Op.IN);
+ RoleByIdsSearch.done();
+
RoleByNameSearch = createSearchBuilder();
RoleByNameSearch.and("roleName", RoleByNameSearch.entity().getName(), SearchCriteria.Op.LIKE);
RoleByNameSearch.and("isPublicRole", RoleByNameSearch.entity().isPublicRole(), SearchCriteria.Op.EQ);
@@ -116,6 +123,16 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
return searchAndCount(sc, new Filter(RoleVO.class, "id", true, startIndex, limit));
}
+ @Override
+ public List<RoleVO> searchByIds(Long... ids) {
+ if (ids == null || ids.length == 0) {
+ return Collections.emptyList();
+ }
+ SearchCriteria<RoleVO> sc = RoleByIdsSearch.create();
+ sc.setParameters("idIN", ids);
+ return listBy(sc);
+ }
+
public void filterPrivateRolesIfNeeded(SearchCriteria<RoleVO> sc, boolean showPrivateRole) {
if (!showPrivateRole) {
sc.setParameters("isPublicRole", true);
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java
index f4d98c3fb7f..7b0500680b9 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java
@@ -65,6 +65,10 @@ public class DiskOfferingDetailVO implements ResourceDetail {
return name;
}
+ public void setName(String name) {
+ this.name = name;
+ }
+
@Override
public String getValue() {
return value;
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
index 1c31b3e0cc4..7aab5bbf7b3 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
@@ -51,4 +51,6 @@ public interface ImageStoreDao extends GenericDao<ImageStoreVO, Long> {
ImageStoreVO findOneByZoneAndProtocol(long zoneId, String protocol);
List<ImageStoreVO> listImageStoresByZoneIds(Long... zoneIds);
+
+ List<ImageStoreVO> listByIds(List<Long> ids);
}
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java
index a4827a1beae..84b88c215ca 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java
@@ -18,12 +18,14 @@
*/
package org.apache.cloudstack.storage.datastore.db;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
import com.cloud.utils.db.Filter;
+import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
@@ -44,6 +46,7 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
private SearchBuilder<ImageStoreVO> zoneProtocolSearch;
private SearchBuilder<ImageStoreVO> zonesInSearch;
+ private SearchBuilder<ImageStoreVO> IdsSearch;
public ImageStoreDaoImpl() {
super();
@@ -62,6 +65,9 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
zonesInSearch.and("zonesIn", zonesInSearch.entity().getDcId(), SearchCriteria.Op.IN);
zonesInSearch.done();
+ IdsSearch = createSearchBuilder();
+ IdsSearch.and("ids", IdsSearch.entity().getId(), SearchCriteria.Op.IN);
+ IdsSearch.done();
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -206,4 +212,14 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
sc.setParametersIfNotNull("zonesIn", zoneIds);
return listBy(sc);
}
+
+ @Override
+ public List<ImageStoreVO> listByIds(List<Long> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return Collections.emptyList();
+ }
+ SearchCriteria<ImageStoreVO> sc = IdsSearch.create();
+ sc.setParameters("ids", ids.toArray());
+ return listBy(sc);
+ }
}
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
index 92b7ad27e45..e97f4638b54 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
@@ -22,6 +22,8 @@ import java.util.Map;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.ScopeType;
import com.cloud.storage.StoragePoolStatus;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDao;
/**
@@ -139,4 +141,10 @@ public interface PrimaryDataStoreDao extends GenericDao<StoragePoolVO, Long> {
List<StoragePoolVO> findPoolsByStorageType(String storageType);
List<StoragePoolVO> listStoragePoolsWithActiveVolumesByOfferingId(long offeringid);
+
+ Pair<List<Long>, Integer> searchForIdsAndCount(Long storagePoolId, String storagePoolName, Long zoneId,
+ String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status,
+ String keyword, Filter searchFilter);
+
+ List<StoragePoolVO> listByIds(List<Long> ids);
}
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
index 554500e2b34..90a692489a1 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
@@ -20,12 +20,16 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.Filter;
import org.apache.commons.collections.CollectionUtils;
import com.cloud.host.Status;
@@ -57,6 +61,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
private final SearchBuilder<StoragePoolVO> DcLocalStorageSearch;
private final GenericSearchBuilder<StoragePoolVO, Long> StatusCountSearch;
private final SearchBuilder<StoragePoolVO> ClustersSearch;
+ private final SearchBuilder<StoragePoolVO> IdsSearch;
@Inject
private StoragePoolDetailsDao _detailsDao;
@@ -143,6 +148,11 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
ClustersSearch = createSearchBuilder();
ClustersSearch.and("clusterIds", ClustersSearch.entity().getClusterId(), Op.IN);
ClustersSearch.and("status", ClustersSearch.entity().getStatus(), Op.EQ);
+ ClustersSearch.done();
+
+ IdsSearch = createSearchBuilder();
+ IdsSearch.and("ids", IdsSearch.entity().getId(), SearchCriteria.Op.IN);
+ IdsSearch.done();
}
@@ -669,4 +679,92 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
throw new CloudRuntimeException("Caught: " + sql, e);
}
}
+
+ @Override
+ public Pair<List<Long>, Integer> searchForIdsAndCount(Long storagePoolId, String storagePoolName, Long zoneId,
+ String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status,
+ String keyword, Filter searchFilter) {
+ SearchCriteria<StoragePoolVO> sc = createStoragePoolSearchCriteria(storagePoolId, storagePoolName, zoneId, path, podId, clusterId, address, scopeType, status, keyword);
+ Pair<List<StoragePoolVO>, Integer> uniquePair = searchAndCount(sc, searchFilter);
+ List<Long> idList = uniquePair.first().stream().map(StoragePoolVO::getId).collect(Collectors.toList());
+ return new Pair<>(idList, uniquePair.second());
+ }
+
+ @Override
+ public List<StoragePoolVO> listByIds(List<Long> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return Collections.emptyList();
+ }
+ SearchCriteria<StoragePoolVO> sc = IdsSearch.create();
+ sc.setParameters("ids", ids.toArray());
+ return listBy(sc);
+ }
+
+ private SearchCriteria<StoragePoolVO> createStoragePoolSearchCriteria(Long storagePoolId, String storagePoolName,
+ Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType,
+ StoragePoolStatus status, String keyword) {
+ SearchBuilder<StoragePoolVO> sb = createSearchBuilder();
+ sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct
+ // ids
+ sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+ sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+ sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ);
+ sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+ sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+ sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
+ sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ);
+ sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ);
+ sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
+ sb.and("parent", sb.entity().getParent(), SearchCriteria.Op.EQ);
+
+ SearchCriteria<StoragePoolVO> sc = sb.create();
+
+ if (keyword != null) {
+ SearchCriteria<StoragePoolVO> ssc = createSearchCriteria();
+ ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+ ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+ sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+ }
+
+ if (storagePoolId != null) {
+ sc.setParameters("id", storagePoolId);
+ }
+
+ if (storagePoolName != null) {
+ sc.setParameters("name", storagePoolName);
+ }
+
+ if (path != null) {
+ sc.setParameters("path", path);
+ }
+ if (zoneId != null) {
+ sc.setParameters("dataCenterId", zoneId);
+ }
+ if (podId != null) {
+ SearchCriteria<StoragePoolVO> ssc = createSearchCriteria();
+ ssc.addOr("podId", SearchCriteria.Op.EQ, podId);
+ ssc.addOr("podId", SearchCriteria.Op.NULL);
+
+ sc.addAnd("podId", SearchCriteria.Op.SC, ssc);
+ }
+ if (address != null) {
+ sc.setParameters("hostAddress", address);
+ }
+ if (clusterId != null) {
+ SearchCriteria<StoragePoolVO> ssc = createSearchCriteria();
+ ssc.addOr("clusterId", SearchCriteria.Op.EQ, clusterId);
+ ssc.addOr("clusterId", SearchCriteria.Op.NULL);
+
+ sc.addAnd("clusterId", SearchCriteria.Op.SC, ssc);
+ }
+ if (scopeType != null) {
+ sc.setParameters("scope", scopeType.toString());
+ }
+ if (status != null) {
+ sc.setParameters("status", status.toString());
+ }
+ sc.setParameters("parent", 0);
+ return sc;
+ }
}
diff --git a/engine/schema/src/main/resources/META-INF/db/views/cloud.service_offering_view.sql b/engine/schema/src/main/resources/META-INF/db/views/cloud.service_offering_view.sql
index e859af482b4..da5172e39cc 100644
--- a/engine/schema/src/main/resources/META-INF/db/views/cloud.service_offering_view.sql
+++ b/engine/schema/src/main/resources/META-INF/db/views/cloud.service_offering_view.sql
@@ -84,7 +84,7 @@ SELECT
FROM
`cloud`.`service_offering`
INNER JOIN
- `cloud`.`disk_offering_view` AS `disk_offering` ON service_offering.disk_offering_id = disk_offering.id
+ `cloud`.`disk_offering` ON service_offering.disk_offering_id = disk_offering.id AND `disk_offering`.`state`='Active'
LEFT JOIN
`cloud`.`service_offering_details` AS `domain_details` ON `domain_details`.`service_offering_id` = `service_offering`.`id` AND `domain_details`.`name`='domainid'
LEFT JOIN
diff --git a/framework/db/src/main/java/com/cloud/utils/db/Attribute.java b/framework/db/src/main/java/com/cloud/utils/db/Attribute.java
index 82c2bdbaa79..3e5128d97b4 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/Attribute.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/Attribute.java
@@ -81,6 +81,7 @@ public class Attribute {
protected String table;
protected String columnName;
+ protected Object value;
protected Field field;
protected int flags;
protected Column column;
@@ -100,6 +101,10 @@ public class Attribute {
this.column = null;
}
+ public Attribute(Object value) {
+ this.value = value;
+ }
+
protected void setupColumnInfo(Class<?> clazz, AttributeOverride[] overrides, String tableName, boolean isEmbedded, boolean isId) {
flags = Flag.Selectable.setTrue(flags);
GeneratedValue gv = field.getAnnotation(GeneratedValue.class);
@@ -214,6 +219,10 @@ public class Attribute {
return field;
}
+ public Object getValue() {
+ return value;
+ }
+
public Object get(Object entity) {
try {
return field.get(entity);
diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericDao.java b/framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
index b2a9e6f733a..2fc02301cb7 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
@@ -286,4 +286,6 @@ public interface GenericDao<T, ID extends Serializable> {
Pair<List<T>, Integer> searchAndDistinctCount(final SearchCriteria<T> sc, final Filter filter, final String[] distinctColumns);
Integer countAll();
+
+ List<T> findByUuids(String... uuidArray);
}
diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
index 577fae1a87d..6724da8b8be 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
@@ -56,6 +56,7 @@ import javax.persistence.Enumerated;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
+import com.amazonaws.util.CollectionUtils;
import org.apache.log4j.Logger;
import com.cloud.utils.DateUtil;
@@ -373,10 +374,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+ List<Attribute> joinAttrList = null;
if (sc != null) {
joins = sc.getJoins();
if (joins != null) {
- addJoins(str, joins);
+ joinAttrList = addJoins(str, joins);
}
}
@@ -396,6 +398,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
try {
pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1;
+
+ if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
+ for (Attribute attr : joinAttrList) {
+ prepareAttribute(i++, pstmt, attr, null);
+ }
+ }
+
if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second());
@@ -448,8 +457,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
joins = sc.getJoins();
+ List<Attribute> joinAttrList = null;
if (joins != null) {
- addJoins(str, joins);
+ joinAttrList = addJoins(str, joins);
}
List<Object> groupByValues = addGroupBy(str, sc);
@@ -462,6 +472,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
try {
pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1;
+
+ if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
+ for (Attribute attr : joinAttrList) {
+ prepareAttribute(i++, pstmt, attr, null);
+ }
+ }
+
if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second());
@@ -1272,12 +1289,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
@DB()
- protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
- addJoins(str, joins, new HashMap<>());
+ protected List<Attribute> addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
+ return addJoins(str, joins, new HashMap<>());
}
@DB()
- protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins, Map<String, Integer> joinedTableNames) {
+ protected List<Attribute> addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins, Map<String, String> joinedTableNames) {
+ List<Attribute> joinAttrList = new ArrayList<>();
boolean hasWhereClause = true;
int fromIndex = str.lastIndexOf("WHERE");
if (fromIndex == -1) {
@@ -1288,8 +1306,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
for (JoinBuilder<SearchCriteria<?>> join : joins) {
- String joinTableName = join.getSecondAttribute().table;
- String joinTableAlias = findNextJoinTableName(joinTableName, joinedTableNames);
+ String joinTableName = join.getSecondAttribute()[0].table;
+ String joinTableAlias;
+ if (StringUtils.isNotEmpty(join.getName())) {
+ joinTableAlias = join.getName();
+ joinedTableNames.put(joinTableName, joinTableAlias);
+ } else {
+ joinTableAlias = joinedTableNames.getOrDefault(joinTableName, joinTableName);
+ }
StringBuilder onClause = new StringBuilder();
onClause.append(" ")
.append(join.getType().getName())
@@ -1298,21 +1322,36 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
if (!joinTableAlias.equals(joinTableName)) {
onClause.append(" ").append(joinTableAlias);
}
- onClause.append(" ON ")
- .append(join.getFirstAttribute().table)
- .append(".")
- .append(join.getFirstAttribute().columnName)
- .append("=");
- if(!joinTableAlias.equals(joinTableName)) {
- onClause.append(joinTableAlias);
- } else {
- onClause.append(joinTableName);
+ onClause.append(" ON ");
+ for (int i = 0; i < join.getFirstAttributes().length; i++) {
+ if (i > 0) {
+ onClause.append(join.getCondition().getName());
+ }
+ if (join.getFirstAttributes()[i].getValue() != null) {
+ onClause.append("?");
+ joinAttrList.add(join.getFirstAttributes()[i]);
+ } else {
+ onClause.append(joinedTableNames.getOrDefault(join.getFirstAttributes()[i].table, join.getFirstAttributes()[i].table))
+ .append(".")
+ .append(join.getFirstAttributes()[i].columnName);
+ }
+ onClause.append("=");
+ if (join.getSecondAttribute()[i].getValue() != null) {
+ onClause.append("?");
+ joinAttrList.add(join.getSecondAttribute()[i]);
+ } else {
+ if(!joinTableAlias.equals(joinTableName)) {
+ onClause.append(joinTableAlias);
+ } else {
+ onClause.append(joinTableName);
+ }
+ onClause.append(".")
+ .append(join.getSecondAttribute()[i].columnName);
+ }
}
- onClause.append(".")
- .append(join.getSecondAttribute().columnName)
- .append(" ");
+ onClause.append(" ");
str.insert(fromIndex, onClause);
- String whereClause = join.getT().getWhereClause();
+ String whereClause = join.getT().getWhereClause(joinTableAlias);
if (StringUtils.isNotEmpty(whereClause)) {
if (!hasWhereClause) {
str.append(" WHERE ");
@@ -1329,20 +1368,10 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
for (JoinBuilder<SearchCriteria<?>> join : joins) {
if (join.getT().getJoins() != null) {
- addJoins(str, join.getT().getJoins(), joinedTableNames);
+ joinAttrList.addAll(addJoins(str, join.getT().getJoins(), joinedTableNames));
}
}
- }
-
- protected static String findNextJoinTableName(String tableName, Map<String, Integer> usedTableNames) {
- if (usedTableNames.containsKey(tableName)) {
- Integer tableCounter = usedTableNames.get(tableName);
- usedTableNames.put(tableName, ++tableCounter);
- tableName = tableName + tableCounter;
- } else {
- usedTableNames.put(tableName, 0);
- }
- return tableName;
+ return joinAttrList;
}
private void removeAndClause(StringBuilder sql) {
@@ -1595,10 +1624,24 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
return;
}
}
- if (attr.field.getType() == String.class) {
- final String str = (String)value;
- if (str == null) {
- pstmt.setString(j, null);
+ if (attr.getValue() != null && attr.getValue() instanceof String) {
+ pstmt.setString(j, (String)attr.getValue());
+ } else if (attr.getValue() != null && attr.getValue() instanceof Long) {
+ pstmt.setLong(j, (Long)attr.getValue());
+ } else if (attr.field.getType() == String.class) {
+ final String str;
+ try {
+ str = (String) value;
+ if (str == null) {
+ pstmt.setString(j, null);
+ return;
+ }
+ } catch (ClassCastException ex) {
+ // This happens when we pass in an integer, long or any other object which can't be cast to String.
+ // Converting to string in case of integer or long can result in different results. Required specifically for details tables.
+ // So, we set the value for the object directly.
+ s_logger.debug("ClassCastException when casting value to String. Setting the value of the object directly.");
+ pstmt.setObject(j, value);
return;
}
final Column column = attr.field.getAnnotation(Column.class);
@@ -2018,10 +2061,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+ List<Attribute> joinAttrList = null;
if (sc != null) {
joins = sc.getJoins();
if (joins != null) {
- addJoins(str, joins);
+ joinAttrList = addJoins(str, joins);
}
}
@@ -2034,6 +2078,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
try {
pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1;
+
+ if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
+ for (Attribute attr : joinAttrList) {
+ prepareAttribute(i++, pstmt, attr, null);
+ }
+ }
+
if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second());
@@ -2081,10 +2132,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+ List<Attribute> joinAttrList = null;
if (sc != null) {
joins = sc.getJoins();
if (joins != null) {
- addJoins(str, joins);
+ joinAttrList = addJoins(str, joins);
}
}
@@ -2093,6 +2145,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
try (PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql)) {
int i = 1;
+
+ if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
+ for (Attribute attr : joinAttrList) {
+ prepareAttribute(i++, pstmt, attr, null);
+ }
+ }
+
if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second());
@@ -2119,6 +2178,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
return getCount(null);
}
+ @Override
+ public List<T> findByUuids(String... uuidArray) {
+ SearchCriteria<T> sc = createSearchCriteria();
+ sc.addAnd("uuid", SearchCriteria.Op.IN, uuidArray);
+ return search(sc, null);
+ }
+
public Integer getCount(SearchCriteria<T> sc) {
sc = checkAndSetRemovedIsNull(sc);
return getCountIncludingRemoved(sc);
@@ -2136,10 +2202,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+ List<Attribute> joinAttrList = null;
if (sc != null) {
joins = sc.getJoins();
if (joins != null) {
- addJoins(str, joins);
+ joinAttrList = addJoins(str, joins);
}
}
@@ -2150,6 +2217,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
try {
pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1;
+
+ if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
+ for (Attribute attr : joinAttrList) {
+ prepareAttribute(i++, pstmt, attr, null);
+ }
+ }
+
if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second());
diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java
index df6f1f7602f..f4385efb3b8 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java
@@ -80,6 +80,12 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return this;
}
+ public GenericSearchBuilder<T, K> and(String joinName, String name, Object field, Op op) {
+ SearchBase<?, ?, ?> join = _joins.get(joinName).getT();
+ constructCondition(joinName, name, " AND ", join._specifiedAttrs.get(0), op);
+ return this;
+ }
+
/**
* Adds an AND condition. Some prefer this method because it looks like
* the actual SQL query.
@@ -134,6 +140,12 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return this;
}
+ protected GenericSearchBuilder<T, K> left(String joinName, Object field, Op op, String name) {
+ SearchBase<?, ?, ?> joinSb = _joins.get(joinName).getT();
+ constructCondition(joinName, name, " ( ", joinSb._specifiedAttrs.get(0), op);
+ return this;
+ }
+
protected Preset left(Object field, Op op) {
Condition condition = constructCondition(UUID.randomUUID().toString(), " ( ", _specifiedAttrs.get(0), op);
return new Preset(this, condition);
@@ -169,6 +181,10 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return left(field, op, name);
}
+ public GenericSearchBuilder<T, K> op(String joinName, String name, Object field, Op op) {
+ return left(joinName, field, op, name);
+ }
+
/**
* Adds an OR condition to the SearchBuilder.
*
@@ -182,6 +198,12 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return this;
}
+ public GenericSearchBuilder<T, K> or(String joinName, String name, Object field, Op op) {
+ SearchBase<?, ?, ?> join = _joins.get(joinName).getT();
+ constructCondition(joinName, name, " OR ", join._specifiedAttrs.get(0), op);
+ return this;
+ }
+
/**
* Adds an OR condition
*
diff --git a/framework/db/src/main/java/com/cloud/utils/db/JoinBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/JoinBuilder.java
index 60e392170be..f0a3ad82596 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/JoinBuilder.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/JoinBuilder.java
@@ -31,17 +31,55 @@ public class JoinBuilder<T> {
return _name;
}
}
+ public enum JoinCondition {
+ AND(" AND "), OR(" OR ");
+
+ private final String name;
+
+ JoinCondition(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
private final T t;
+ private final String name;
private JoinType type;
- private Attribute firstAttribute;
- private Attribute secondAttribute;
- public JoinBuilder(T t, Attribute firstAttribute, Attribute secondAttribute, JoinType type) {
+ private JoinCondition condition;
+ private Attribute[] firstAttributes;
+ private Attribute[] secondAttribute;
+
+ public JoinBuilder(String name, T t, Attribute firstAttributes, Attribute secondAttribute, JoinType type) {
+ this.name = name;
this.t = t;
- this.firstAttribute = firstAttribute;
+ this.firstAttributes = new Attribute[]{firstAttributes};
+ this.secondAttribute = new Attribute[]{secondAttribute};
+ this.type = type;
+ }
+
+ public JoinBuilder(String name, T t, Attribute[] firstAttributes, Attribute[] secondAttribute, JoinType type) {
+ this.name = name;
+ this.t = t;
+ this.firstAttributes = firstAttributes;
+ this.secondAttribute = secondAttribute;
+ this.type = type;
+ }
+
+ public JoinBuilder(String name, T t, Attribute[] firstAttributes, Attribute[] secondAttribute, JoinType type, JoinCondition condition) {
+ this.name = name;
+ this.t = t;
+ this.firstAttributes = firstAttributes;
this.secondAttribute = secondAttribute;
this.type = type;
+ this.condition = condition;
+ }
+
+ public String getName() {
+ return name;
}
public T getT() {
@@ -56,19 +94,23 @@ public class JoinBuilder<T> {
this.type = type;
}
- public Attribute getFirstAttribute() {
- return firstAttribute;
+ public JoinCondition getCondition() {
+ return condition;
+ }
+
+ public Attribute[] getFirstAttributes() {
+ return firstAttributes;
}
- public void setFirstAttribute(Attribute firstAttribute) {
- this.firstAttribute = firstAttribute;
+ public void setFirstAttributes(Attribute[] firstAttributes) {
+ this.firstAttributes = firstAttributes;
}
- public Attribute getSecondAttribute() {
+ public Attribute[] getSecondAttribute() {
return secondAttribute;
}
- public void setSecondAttribute(Attribute secondAttribute) {
+ public void setSecondAttribute(Attribute[] secondAttribute) {
this.secondAttribute = secondAttribute;
}
diff --git a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java
index 3d41a62b43c..fcc9ded684d 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java
@@ -36,6 +36,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
+import org.apache.commons.lang3.StringUtils;
/**
* SearchBase contains the methods that are used to build up search
@@ -70,6 +71,14 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
init(entityType, resultType);
}
+ public SearchBase<?, ?, ?> getJoinSB(String name) {
+ JoinBuilder<SearchBase<?, ?, ?>> jb = null;
+ if (_joins != null) {
+ jb = _joins.get(name);
+ }
+ return jb == null ? null : jb.getT();
+ }
+
protected void init(final Class<T> entityType, final Class<K> resultType) {
_dao = (GenericDaoBase<? extends T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
if (_dao == null) {
@@ -194,15 +203,45 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
* @param joinType type of join
* @return itself
*/
- @SuppressWarnings("unchecked")
public J join(final String name, final SearchBase<?, ?, ?> builder, final Object joinField1, final Object joinField2, final JoinBuilder.JoinType joinType) {
- assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
- assert _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
- assert builder._entity != null : "SearchBuilder cannot be modified once it has been setup";
- assert builder._specifiedAttrs.size() == 1 : "You didn't select the attribute.";
- assert builder != this : "You can't add yourself, can you? Really think about it!";
+ if (_specifiedAttrs.size() != 1)
+ throw new CloudRuntimeException("You didn't select the attribute.");
+ if (builder._specifiedAttrs.size() != 1)
+ throw new CloudRuntimeException("You didn't select the attribute.");
+
+ return join(name, builder, joinType, null, joinField1, joinField2);
+ }
+
- final JoinBuilder<SearchBase<?, ?, ?>> t = new JoinBuilder<SearchBase<?, ?, ?>>(builder, _specifiedAttrs.get(0), builder._specifiedAttrs.get(0), joinType);
+ /**
+ * joins this search with another search with multiple conditions in the join clause
+ *
+ * @param name name given to the other search. used for setJoinParameters.
+ * @param builder The other search
+ * @param joinType type of join
+ * @param condition condition to be used for multiple conditions in the join clause
+ * @param joinFields fields the first and second table used to perform the join.
+ * The fields should be in the order of the checks between the two tables.
+ *
+ * @return
+ */
+ public J join(final String name, final SearchBase<?, ?, ?> builder, final JoinBuilder.JoinType joinType, final
+ JoinBuilder.JoinCondition condition, final Object... joinFields) {
+ if (_entity == null)
+ throw new CloudRuntimeException("SearchBuilder cannot be modified once it has been setup");
+ if (_specifiedAttrs.isEmpty())
+ throw new CloudRuntimeException("Attribute not specified.");
+ if (builder._entity == null)
+ throw new CloudRuntimeException("SearchBuilder cannot be modified once it has been setup");
+ if (builder._specifiedAttrs.isEmpty())
+ throw new CloudRuntimeException("Attribute not specified.");
+ if (builder == this)
+ throw new CloudRuntimeException("Can't join with itself. Create a new SearchBuilder for the same entity and use that.");
+ if (_specifiedAttrs.size() != builder._specifiedAttrs.size())
+ throw new CloudRuntimeException("Number of attributes to join on must be the same.");
+
+ final JoinBuilder<SearchBase<?, ?, ?>> t = new JoinBuilder<>(name, builder, _specifiedAttrs.toArray(new Attribute[0]),
+ builder._specifiedAttrs.toArray(new Attribute[0]), joinType, condition);
if (_joins == null) {
_joins = new HashMap<String, JoinBuilder<SearchBase<?, ?, ?>>>();
}
@@ -223,6 +262,16 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
_specifiedAttrs.add(attr);
}
+ /*
+ Allows to set conditions in join where one entity is equivalent to a string or a long
+ e.g. join("vm", vmSearch, VmDetailVO.class, entity.getName(), "vm.id", SearchCriteria.Op.EQ);
+ will create a condition 'vm.name = "vm.id"'
+ */
+ protected void setAttr(final Object obj) {
+ final Attribute attr = new Attribute(obj);
+ _specifiedAttrs.add(attr);
+ }
+
/**
* @return entity object. This allows the caller to use the entity return
* to specify the field to be selected in many of the search parameters.
@@ -242,17 +291,26 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
return _specifiedAttrs;
}
- protected Condition constructCondition(final String conditionName, final String cond, final Attribute attr, final Op op) {
+ protected Condition constructCondition(final String joinName, final String conditionName, final String cond, final Attribute attr, final Op op) {
assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
assert op == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
assert op != Op.SC : "Call join";
final Condition condition = new Condition(conditionName, cond, attr, op);
+ if (StringUtils.isNotEmpty(joinName)) {
+ condition.setJoinName(joinName);
+ }
_conditions.add(condition);
_specifiedAttrs.clear();
return condition;
}
+
+ protected Condition constructCondition(final String conditionName, final String cond, final Attribute attr, final Op op) {
+ return constructCondition(null, conditionName, cond, attr, op);
+ }
+
+
/**
* creates the SearchCriteria so the actual values can be filled in.
*
@@ -364,6 +422,7 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
protected static class Condition {
protected final String name;
protected final String cond;
+ protected String joinName;
protected final Op op;
protected final Attribute attr;
protected Object[] presets;
@@ -388,11 +447,15 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
this.presets = presets;
}
+ public void setJoinName(final String joinName) {
+ this.joinName = joinName;
+ }
+
public Object[] getPresets() {
return presets;
}
- public void toSql(final StringBuilder sql, final Object[] params, final int count) {
+ public void toSql(final StringBuilder sql, String tableAlias, final Object[] params, final int count) {
if (count > 0) {
sql.append(cond);
}
@@ -414,7 +477,15 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
sql.append(" FIND_IN_SET(?, ");
}
- sql.append(attr.table).append(".").append(attr.columnName).append(op.toString());
+ if (tableAlias == null) {
+ if (joinName != null) {
+ tableAlias = joinName;
+ } else {
+ tableAlias = attr.table;
+ }
+ }
+
+ sql.append(tableAlias).append(".").append(attr.columnName).append(op.toString());
if (op == Op.IN && params.length == 1) {
sql.delete(sql.length() - op.toString().length(), sql.length());
sql.append("=?");
@@ -485,6 +556,8 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
final String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
set(fieldName);
return null;
+ } else if (name.equals("setLong") || name.equals("setString")) {
+ setAttr(args[0]);
} else {
final Column ann = method.getAnnotation(Column.class);
if (ann != null) {
diff --git a/framework/db/src/main/java/com/cloud/utils/db/SearchCriteria.java b/framework/db/src/main/java/com/cloud/utils/db/SearchCriteria.java
index 6f90d2391e6..8affbd5300a 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/SearchCriteria.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/SearchCriteria.java
@@ -106,7 +106,7 @@ public class SearchCriteria<K> {
for (Map.Entry<String, JoinBuilder<SearchBase<?, ?, ?>>> entry : sb._joins.entrySet()) {
JoinBuilder<SearchBase<?, ?, ?>> value = entry.getValue();
_joins.put(entry.getKey(),
- new JoinBuilder<SearchCriteria<?>>(value.getT().create(), value.getFirstAttribute(), value.getSecondAttribute(), value.getType()));
+ new JoinBuilder<SearchCriteria<?>>(entry.getKey(), value.getT().create(), value.getFirstAttributes(), value.getSecondAttribute(), value.getType(), value.getCondition()));
}
}
_selects = sb._selects;
@@ -250,7 +250,7 @@ public class SearchCriteria<K> {
_additionals.add(condition);
}
- public String getWhereClause() {
+ public String getWhereClause(String tableAlias) {
StringBuilder sql = new StringBuilder();
int i = 0;
for (Condition condition : _conditions) {
@@ -259,7 +259,7 @@ public class SearchCriteria<K> {
}
Object[] params = _params.get(condition.name);
if ((condition.op == null || condition.op.params == 0) || (params != null)) {
- condition.toSql(sql, params, i++);
+ condition.toSql(sql, tableAlias, params, i++);
}
}
@@ -269,13 +269,17 @@ public class SearchCriteria<K> {
}
Object[] params = _params.get(condition.name);
if ((condition.op.params == 0) || (params != null)) {
- condition.toSql(sql, params, i++);
+ condition.toSql(sql, tableAlias, params, i++);
}
}
return sql.toString();
}
+ public String getWhereClause() {
+ return getWhereClause(null);
+ }
+
public List<Pair<Attribute, Object>> getValues() {
ArrayList<Pair<Attribute, Object>> params = new ArrayList<Pair<Attribute, Object>>(_params.size());
for (Condition condition : _conditions) {
diff --git a/framework/db/src/test/java/com/cloud/utils/db/GenericDaoBaseTest.java b/framework/db/src/test/java/com/cloud/utils/db/GenericDaoBaseTest.java
index b950501337b..308600341c3 100644
--- a/framework/db/src/test/java/com/cloud/utils/db/GenericDaoBaseTest.java
+++ b/framework/db/src/test/java/com/cloud/utils/db/GenericDaoBaseTest.java
@@ -20,8 +20,6 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
@@ -229,12 +227,16 @@ public class GenericDaoBaseTest {
Attribute attr2 = new Attribute("table2", "column2");
Attribute attr3 = new Attribute("table3", "column1");
Attribute attr4 = new Attribute("table4", "column2");
+ Attribute attr5 = new Attribute("table3", "column1");
+ Attribute attr6 = new Attribute("XYZ");
- joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), attr1, attr2, JoinBuilder.JoinType.INNER));
- joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), attr3, attr4, JoinBuilder.JoinType.INNER));
+ joins.add(new JoinBuilder<>("", dbTestDao.createSearchCriteria(), attr1, attr2, JoinBuilder.JoinType.INNER));
+ joins.add(new JoinBuilder<>("", dbTestDao.createSearchCriteria(),
+ new Attribute[]{attr3, attr5}, new Attribute[]{attr4, attr6}, JoinBuilder.JoinType.INNER, JoinBuilder.JoinCondition.OR));
dbTestDao.addJoins(joinString, joins);
- Assert.assertEquals(" INNER JOIN table2 ON table1.column1=table2.column2 INNER JOIN table4 ON table3.column1=table4.column2 ", joinString.toString());
+ Assert.assertEquals(" INNER JOIN table2 ON table1.column1=table2.column2 " +
+ " INNER JOIN table4 ON table3.column1=table4.column2 OR table3.column1=? ", joinString.toString());
}
@Test
@@ -248,22 +250,17 @@ public class GenericDaoBaseTest {
Attribute tBc2 = new Attribute("tableB", "column2");
Attribute tCc3 = new Attribute("tableC", "column3");
Attribute tDc4 = new Attribute("tableD", "column4");
+ Attribute tDc5 = new Attribute("tableD", "column5");
+ Attribute attr = new Attribute(123);
- joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tBc2, tAc1, JoinBuilder.JoinType.INNER));
- joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tCc3, tAc2, JoinBuilder.JoinType.INNER));
- joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tDc4, tAc3, JoinBuilder.JoinType.INNER));
+ joins.add(new JoinBuilder<>("tableA1Alias", dbTestDao.createSearchCriteria(), tBc2, tAc1, JoinBuilder.JoinType.INNER));
+ joins.add(new JoinBuilder<>("tableA2Alias", dbTestDao.createSearchCriteria(), tCc3, tAc2, JoinBuilder.JoinType.INNER));
+ joins.add(new JoinBuilder<>("tableA3Alias", dbTestDao.createSearchCriteria(),
+ new Attribute[]{tDc4, tDc5}, new Attribute[]{tAc3, attr}, JoinBuilder.JoinType.INNER, JoinBuilder.JoinCondition.AND));
dbTestDao.addJoins(joinString, joins);
- Assert.assertEquals(" INNER JOIN tableA ON tableB.column2=tableA.column1 INNER JOIN tableA tableA1 ON tableC.column3=tableA1.column2 INNER JOIN tableA tableA2 ON tableD.column4=tableA2.column3 ", joinString.toString());
- }
-
- @Test
- public void findNextTableNameTest() {
- Map<String, Integer> usedTables = new HashMap<>();
-
- Assert.assertEquals("tableA", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
- Assert.assertEquals("tableA1", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
- Assert.assertEquals("tableA2", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
- Assert.assertEquals("tableA3", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
+ Assert.assertEquals(" INNER JOIN tableA tableA1Alias ON tableB.column2=tableA1Alias.column1 " +
+ " INNER JOIN tableA tableA2Alias ON tableC.column3=tableA2Alias.column2 " +
+ " INNER JOIN tableA tableA3Alias ON tableD.column4=tableA3Alias.column3 AND tableD.column5=? ", joinString.toString());
}
}
diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
index 11c33968a04..136976cafc2 100644
--- a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
+++ b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
@@ -27,10 +27,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.dc.ClusterVO;
import com.cloud.utils.Ternary;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.ListClustersMetricsCmd;
@@ -634,6 +636,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
@Override
public List<StoragePoolMetricsResponse> listStoragePoolMetrics(List<StoragePoolResponse> poolResponses) {
final List<StoragePoolMetricsResponse> metricsResponses = new ArrayList<>();
+ Map<String, Long> clusterUuidToIdMap = clusterDao.findByUuids(poolResponses.stream().map(StoragePoolResponse::getClusterId).toArray(String[]::new)).stream().collect(Collectors.toMap(ClusterVO::getUuid, ClusterVO::getId));
for (final StoragePoolResponse poolResponse: poolResponses) {
StoragePoolMetricsResponse metricsResponse = new StoragePoolMetricsResponse();
@@ -643,11 +646,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate storagepool metrics response");
}
- Long poolClusterId = null;
- final Cluster cluster = clusterDao.findByUuid(poolResponse.getClusterId());
- if (cluster != null) {
- poolClusterId = cluster.getId();
- }
+ Long poolClusterId = clusterUuidToIdMap.get(poolResponse.getClusterId());
final Double storageThreshold = AlertManager.StorageCapacityThreshold.valueIn(poolClusterId);
final Double storageDisableThreshold = CapacityManager.StorageCapacityDisableThreshold.valueIn(poolClusterId);
diff --git a/server/src/main/java/com/cloud/api/ApiDBUtils.java b/server/src/main/java/com/cloud/api/ApiDBUtils.java
index 3cade046c74..97ecd982f53 100644
--- a/server/src/main/java/com/cloud/api/ApiDBUtils.java
+++ b/server/src/main/java/com/cloud/api/ApiDBUtils.java
@@ -17,12 +17,15 @@
package com.cloud.api;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
@@ -2082,6 +2085,29 @@ public class ApiDBUtils {
return response;
}
+ public static List<AccountResponse> newAccountResponses(ResponseView view, EnumSet<DomainDetails> details, AccountJoinVO... accounts) {
+ List<AccountResponse> responseList = new ArrayList<>();
+
+ List<Long> roleIdList = Arrays.stream(accounts).map(AccountJoinVO::getRoleId).collect(Collectors.toList());
+ Map<Long,Role> roleIdMap = s_roleService.findRoles(roleIdList, false).stream().collect(Collectors.toMap(Role::getId, Function.identity()));
+
+ for (AccountJoinVO account : accounts) {
+ AccountResponse response = s_accountJoinDao.newAccountResponse(view, details, account);
+ // Populate account role information
+ if (account.getRoleId() != null) {
+ Role role = roleIdMap.get(account.getRoleId());
+ if (role != null) {
+ response.setRoleId(role.getUuid());
+ response.setRoleType(role.getRoleType());
+ response.setRoleName(role.getName());
+ }
+ }
+ responseList.add(response);
+ }
+
+ return responseList;
+ }
+
public static AccountJoinVO newAccountView(Account e) {
return s_accountJoinDao.newAccountView(e);
}
diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
index c3807fdb8d7..db462373eed 100644
--- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
@@ -36,6 +36,11 @@ import javax.inject.Inject;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.event.EventVO;
+import com.cloud.event.dao.EventDao;
+import com.cloud.host.HostVO;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.service.ServiceOfferingDetailsVO;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
@@ -50,6 +55,7 @@ import com.cloud.network.dao.PublicIpQuarantineDao;
import com.cloud.network.PublicIpQuarantine;
import com.cloud.network.vo.PublicIpQuarantineVO;
import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.AccountVO;
import com.cloud.user.SSHKeyPairVO;
import com.cloud.user.dao.SSHKeyPairDao;
import com.cloud.vm.InstanceGroupVMMapVO;
@@ -58,6 +64,7 @@ import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.dao.InstanceGroupVMMapDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.storage.VolumeVO;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker;
@@ -161,7 +168,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.outofbandmanagement.OutOfBandManagementVO;
+import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao;
import org.apache.cloudstack.query.QueryService;
+import org.apache.cloudstack.resourcedetail.DiskOfferingDetailVO;
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
import org.apache.cloudstack.secstorage.HeuristicVO;
import org.apache.cloudstack.secstorage.dao.SecondaryStorageHeuristicDao;
@@ -176,6 +186,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@@ -254,7 +265,6 @@ import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.security.SecurityGroupVMMapVO;
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
import com.cloud.org.Grouping;
import com.cloud.projects.Project;
import com.cloud.projects.Project.ListProjectResourcesCriteria;
@@ -287,7 +297,6 @@ import com.cloud.storage.StoragePoolTagVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeApiServiceImpl;
-import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.BucketDao;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.StoragePoolTagsDao;
@@ -351,6 +360,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
@Inject
private UserAccountJoinDao _userAccountJoinDao;
+ @Inject
+ private EventDao eventDao;
+
@Inject
private EventJoinDao _eventJoinDao;
@@ -539,6 +551,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
@Inject
private HostDao hostDao;
+ @Inject
+ private OutOfBandManagementDao outOfBandManagementDao;
+
@Inject
private InstanceGroupVMMapDao instanceGroupVMMapDao;
@@ -788,9 +803,23 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
private Pair<List<EventJoinVO>, Integer> searchForEventsInternal(ListEventsCmd cmd) {
+ Pair<List<Long>, Integer> eventIdPage = searchForEventIdsAndCount(cmd);
+
+ Integer count = eventIdPage.second();
+ Long[] idArray = eventIdPage.first().toArray(new Long[0]);
+
+ if (count == 0) {
+ return new Pair<>(new ArrayList<>(), count);
+ }
+
+ List<EventJoinVO> events = _eventJoinDao.searchByIds(idArray);
+ return new Pair<>(events, count);
+ }
+
+ private Pair<List<Long>, Integer> searchForEventIdsAndCount(ListEventsCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
boolean isRootAdmin = accountMgr.isRootAdmin(caller.getId());
- List<Long> permittedAccounts = new ArrayList<Long>();
+ List<Long> permittedAccounts = new ArrayList<>();
Long id = cmd.getId();
String type = cmd.getType();
@@ -839,32 +868,40 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Boolean isRecursive = domainIdRecursiveListProject.second();
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
- Filter searchFilter = new Filter(EventJoinVO.class, "createDate", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+ Filter searchFilter = new Filter(EventVO.class, "createDate", false, cmd.getStartIndex(), cmd.getPageSizeVal());
// additional order by since createdDate does not have milliseconds
// and two events, created within one second can be incorrectly ordered (for example VM.CREATE Completed before Scheduled)
- searchFilter.addOrderBy(EventJoinVO.class, "id", false);
+ searchFilter.addOrderBy(EventVO.class, "id", false);
+
+ SearchBuilder<EventVO> eventSearchBuilder = eventDao.createSearchBuilder();
+ eventSearchBuilder.select(null, Func.DISTINCT, eventSearchBuilder.entity().getId());
+ accountMgr.buildACLSearchBuilder(eventSearchBuilder, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+ eventSearchBuilder.and("id", eventSearchBuilder.entity().getId(), SearchCriteria.Op.EQ);
+ eventSearchBuilder.and("levelL", eventSearchBuilder.entity().getLevel(), SearchCriteria.Op.LIKE);
+ eventSearchBuilder.and("levelEQ", eventSearchBuilder.entity().getLevel(), SearchCriteria.Op.EQ);
+ eventSearchBuilder.and("type", eventSearchBuilder.entity().getType(), SearchCriteria.Op.EQ);
+ eventSearchBuilder.and("createDateB", eventSearchBuilder.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
+ eventSearchBuilder.and("createDateG", eventSearchBuilder.entity().getCreateDate(), SearchCriteria.Op.GTEQ);
+ eventSearchBuilder.and("createDateL", eventSearchBuilder.entity().getCreateDate(), SearchCriteria.Op.LTEQ);
+ eventSearchBuilder.and("state", eventSearchBuilder.entity().getState(), SearchCriteria.Op.NEQ);
+ eventSearchBuilder.or("startId", eventSearchBuilder.entity().getStartId(), SearchCriteria.Op.EQ);
+ eventSearchBuilder.and("createDate", eventSearchBuilder.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
+ eventSearchBuilder.and("displayEvent", eventSearchBuilder.entity().isDisplay(), SearchCriteria.Op.EQ);
+ eventSearchBuilder.and("archived", eventSearchBuilder.entity().getArchived(), SearchCriteria.Op.EQ);
+ eventSearchBuilder.and("resourceId", eventSearchBuilder.entity().getResourceId(), SearchCriteria.Op.EQ);
+ eventSearchBuilder.and("resourceType", eventSearchBuilder.entity().getResourceType(), SearchCriteria.Op.EQ);
- SearchBuilder<EventJoinVO> sb = _eventJoinDao.createSearchBuilder();
- accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("levelL", sb.entity().getLevel(), SearchCriteria.Op.LIKE);
- sb.and("levelEQ", sb.entity().getLevel(), SearchCriteria.Op.EQ);
- sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
- sb.and("createDateB", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
- sb.and("createDateG", sb.entity().getCreateDate(), SearchCriteria.Op.GTEQ);
- sb.and("createDateL", sb.entity().getCreateDate(), SearchCriteria.Op.LTEQ);
- sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
- sb.or("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ);
- sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
- sb.and("displayEvent", sb.entity().getDisplay(), SearchCriteria.Op.EQ);
- sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ);
- sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
- sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
+ if (keyword != null) {
+ eventSearchBuilder.and().op("keywordType", eventSearchBuilder.entity().getType(), SearchCriteria.Op.LIKE);
+ eventSearchBuilder.or("keywordDescription", eventSearchBuilder.entity().getDescription(), SearchCriteria.Op.LIKE);
+ eventSearchBuilder.or("keywordLevel", eventSearchBuilder.entity().getLevel(), SearchCriteria.Op.LIKE);
+ eventSearchBuilder.cp();
+ }
- SearchCriteria<EventJoinVO> sc = sb.create();
+ SearchCriteria<EventVO> sc = eventSearchBuilder.create();
// building ACL condition
- accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+ accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
// For end users display only enabled events
if (!accountMgr.isRootAdmin(caller.getId())) {
@@ -883,11 +920,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
if (keyword != null) {
- SearchCriteria<EventJoinVO> ssc = _eventJoinDao.createSearchCriteria();
- ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("level", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- sc.addAnd("level", SearchCriteria.Op.SC, ssc);
+ sc.setParameters("keywordType", "%" + keyword + "%");
+ sc.setParameters("keywordDescription", "%" + keyword + "%");
+ sc.setParameters("keywordLevel", "%" + keyword + "%");
}
if (level != null) {
@@ -918,7 +953,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
sc.setParameters("archived", cmd.getArchived());
}
- Pair<List<EventJoinVO>, Integer> eventPair = null;
+ Pair<List<Long>, Integer> eventPair = null;
// event_view will not have duplicate rows for each event, so
// searchAndCount should be good enough.
if ((entryTime != null) && (duration != null)) {
@@ -942,11 +977,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
* _eventDao.findCompletedEvent(event.getId()); if (completedEvent
* == null) { pendingEvents.add(event); } } return pendingEvents;
*/
+ eventPair = new Pair<>(new ArrayList<>(), 0);
} else {
- eventPair = _eventJoinDao.searchAndCount(sc, searchFilter);
+ Pair<List<EventVO>, Integer> uniqueEventPair = eventDao.searchAndCount(sc, searchFilter);
+ Integer count = uniqueEventPair.second();
+ List<Long> eventIds = uniqueEventPair.first().stream().map(EventVO::getId).collect(Collectors.toList());
+ eventPair = new Pair<>(eventIds, count);
}
return eventPair;
-
}
@Override
@@ -1131,7 +1169,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
// search vm details by ids
- List<UserVmJoinVO> vms = _userVmJoinDao.searchByIds( idArray);
+ List<UserVmJoinVO> vms = _userVmJoinDao.searchByIds(idArray);
return new Pair<>(vms, count);
}
@@ -2166,7 +2204,19 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
public Pair<List<HostJoinVO>, Integer> searchForServersInternal(ListHostsCmd cmd) {
+ Pair<List<Long>, Integer> serverIdPage = searchForServerIdsAndCount(cmd);
+
+ Integer count = serverIdPage.second();
+ Long[] idArray = serverIdPage.first().toArray(new Long[0]);
+
+ if (count == 0) {
+ return new Pair<>(new ArrayList<>(), count);
+ }
+ List<HostJoinVO> servers = hostJoinDao.searchByIds(idArray);
+ return new Pair<>(servers, count);
+ }
+ public Pair<List<Long>, Integer> searchForServerIdsAndCount(ListHostsCmd cmd) {
Long zoneId = accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
Object name = cmd.getHostName();
Object type = cmd.getType();
@@ -2183,44 +2233,55 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Long pageSize = cmd.getPageSizeVal();
Hypervisor.HypervisorType hypervisorType = cmd.getHypervisor();
- Filter searchFilter = new Filter(HostJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+ Filter searchFilter = new Filter(HostVO.class, "id", Boolean.TRUE, startIndex, pageSize);
- SearchBuilder<HostJoinVO> sb = hostJoinDao.createSearchBuilder();
- sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+ SearchBuilder<HostVO> hostSearchBuilder = hostDao.createSearchBuilder();
+ hostSearchBuilder.select(null, Func.DISTINCT, hostSearchBuilder.entity().getId()); // select distinct
// ids
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
- sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
- sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
- sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
- sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
- sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
- sb.and("oobmEnabled", sb.entity().isOutOfBandManagementEnabled(), SearchCriteria.Op.EQ);
- sb.and("powerState", sb.entity().getOutOfBandManagementPowerState(), SearchCriteria.Op.EQ);
- sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
- sb.and("hypervisor_type", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("id", hostSearchBuilder.entity().getId(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("name", hostSearchBuilder.entity().getName(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("type", hostSearchBuilder.entity().getType(), SearchCriteria.Op.LIKE);
+ hostSearchBuilder.and("status", hostSearchBuilder.entity().getStatus(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("dataCenterId", hostSearchBuilder.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("podId", hostSearchBuilder.entity().getPodId(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("clusterId", hostSearchBuilder.entity().getClusterId(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("resourceState", hostSearchBuilder.entity().getResourceState(), SearchCriteria.Op.EQ);
+ hostSearchBuilder.and("hypervisor_type", hostSearchBuilder.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+
+ if (keyword != null) {
+ hostSearchBuilder.and().op("keywordName", hostSearchBuilder.entity().getName(), SearchCriteria.Op.LIKE);
+ hostSearchBuilder.or("keywordStatus", hostSearchBuilder.entity().getStatus(), SearchCriteria.Op.LIKE);
+ hostSearchBuilder.or("keywordType", hostSearchBuilder.entity().getType(), SearchCriteria.Op.LIKE);
+ hostSearchBuilder.cp();
+ }
+
+ if (outOfBandManagementEnabled != null || powerState != null) {
+ SearchBuilder<OutOfBandManagementVO> oobmSearch = outOfBandManagementDao.createSearchBuilder();
+ oobmSearch.and("oobmEnabled", oobmSearch.entity().isEnabled(), SearchCriteria.Op.EQ);
+ oobmSearch.and("powerState", oobmSearch.entity().getPowerState(), SearchCriteria.Op.EQ);
+
+ hostSearchBuilder.join("oobmSearch", oobmSearch, hostSearchBuilder.entity().getId(), oobmSearch.entity().getHostId(), JoinBuilder.JoinType.INNER);
+ }
String haTag = _haMgr.getHaTag();
if (haHosts != null && haTag != null && !haTag.isEmpty()) {
+ SearchBuilder<HostTagVO> hostTagSearchBuilder = _hostTagDao.createSearchBuilder();
if ((Boolean)haHosts) {
- sb.and("tag", sb.entity().getTag(), SearchCriteria.Op.EQ);
+ hostTagSearchBuilder.and("tag", hostTagSearchBuilder.entity().getName(), SearchCriteria.Op.EQ);
} else {
- sb.and().op("tag", sb.entity().getTag(), SearchCriteria.Op.NEQ);
- sb.or("tagNull", sb.entity().getTag(), SearchCriteria.Op.NULL);
- sb.cp();
+ hostTagSearchBuilder.and().op("tag", hostTagSearchBuilder.entity().getName(), Op.NEQ);
+ hostTagSearchBuilder.or("tagNull", hostTagSearchBuilder.entity().getName(), Op.NULL);
+ hostTagSearchBuilder.cp();
}
-
+ hostSearchBuilder.join("hostTagSearch", hostTagSearchBuilder, hostSearchBuilder.entity().getId(), hostTagSearchBuilder.entity().getHostId(), JoinBuilder.JoinType.LEFT);
}
- SearchCriteria<HostJoinVO> sc = sb.create();
+ SearchCriteria<HostVO> sc = hostSearchBuilder.create();
if (keyword != null) {
- SearchCriteria<HostJoinVO> ssc = hostJoinDao.createSearchCriteria();
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("status", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+ sc.setParameters("keywordName", "%" + keyword + "%");
+ sc.setParameters("keywordStatus", "%" + keyword + "%");
+ sc.setParameters("keywordType", "%" + keyword + "%");
}
if (id != null) {
@@ -2247,11 +2308,11 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
if (outOfBandManagementEnabled != null) {
- sc.setParameters("oobmEnabled", outOfBandManagementEnabled);
+ sc.setJoinParameters("oobmSearch", "oobmEnabled", outOfBandManagementEnabled);
}
if (powerState != null) {
- sc.setParameters("powerState", powerState);
+ sc.setJoinParameters("oobmSearch", "powerState", powerState);
}
if (resourceState != null) {
@@ -2259,28 +2320,17 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
if (haHosts != null && haTag != null && !haTag.isEmpty()) {
- sc.setParameters("tag", haTag);
+ sc.setJoinParameters("hostTagSearch", "tag", haTag);
}
if (hypervisorType != HypervisorType.None && hypervisorType != HypervisorType.Any) {
sc.setParameters("hypervisor_type", hypervisorType);
}
- // search host details by ids
- Pair<List<HostJoinVO>, Integer> uniqueHostPair = hostJoinDao.searchAndCount(sc, searchFilter);
- Integer count = uniqueHostPair.second();
- if (count.intValue() == 0) {
- // handle empty result cases
- return uniqueHostPair;
- }
- List<HostJoinVO> uniqueHosts = uniqueHostPair.first();
- Long[] hostIds = new Long[uniqueHosts.size()];
- int i = 0;
- for (HostJoinVO v : uniqueHosts) {
- hostIds[i++] = v.getId();
- }
- List<HostJoinVO> hosts = hostJoinDao.searchByIds(hostIds);
- return new Pair<List<HostJoinVO>, Integer>(hosts, count);
+ Pair<List<HostVO>, Integer> uniqueHostPair = hostDao.searchAndCount(sc, searchFilter);
+ Integer count = uniqueHostPair.second();
+ List<Long> hostIds = uniqueHostPair.first().stream().map(HostVO::getId).collect(Collectors.toList());
+ return new Pair<>(hostIds, count);
}
@Override
@@ -2331,6 +2381,19 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
private Pair<List<VolumeJoinVO>, Integer> searchForVolumesInternal(ListVolumesCmd cmd) {
+ Pair<List<Long>, Integer> volumeIdPage = searchForVolumeIdsAndCount(cmd);
+
+ Integer count = volumeIdPage.second();
+ Long[] idArray = volumeIdPage.first().toArray(new Long[0]);
+
+ if (count == 0) {
+ return new Pair<>(new ArrayList<>(), count);
+ }
+
+ List<VolumeJoinVO> vms = _volumeJoinDao.searchByIds(idArray);
+ return new Pair<>(vms, count);
+ }
+ private Pair<List<Long>, Integer> searchForVolumeIdsAndCount(ListVolumesCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedAccounts = new ArrayList<Long>();
@@ -2358,61 +2421,97 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Long domainId = domainIdRecursiveListProject.first();
Boolean isRecursive = domainIdRecursiveListProject.second();
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
- Filter searchFilter = new Filter(VolumeJoinVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+ Filter searchFilter = new Filter(VolumeVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
- // hack for now, this should be done better but due to needing a join I
- // opted to
- // do this quickly and worry about making it pretty later
- SearchBuilder<VolumeJoinVO> sb = _volumeJoinDao.createSearchBuilder();
- sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
- // ids to get
- // number of
- // records with
- // pagination
- accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+ SearchBuilder<VolumeVO> volumeSearchBuilder = volumeDao.createSearchBuilder();
+ volumeSearchBuilder.select(null, Func.DISTINCT, volumeSearchBuilder.entity().getId()); // select distinct
+ accountMgr.buildACLSearchBuilder(volumeSearchBuilder, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
- sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
- sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE);
- sb.and("uuid", sb.entity().getUuid(), SearchCriteria.Op.NNULL);
- sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ);
- sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
- sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+ if (CollectionUtils.isNotEmpty(ids)) {
+ volumeSearchBuilder.and("idIN", volumeSearchBuilder.entity().getId(), SearchCriteria.Op.IN);
+ }
+
+ volumeSearchBuilder.and("name", volumeSearchBuilder.entity().getName(), SearchCriteria.Op.EQ);
+ volumeSearchBuilder.and("volumeType", volumeSearchBuilder.entity().getVolumeType(), SearchCriteria.Op.LIKE);
+ volumeSearchBuilder.and("uuid", volumeSearchBuilder.entity().getUuid(), SearchCriteria.Op.NNULL);
+ volumeSearchBuilder.and("instanceId", volumeSearchBuilder.entity().getInstanceId(), SearchCriteria.Op.EQ);
+ volumeSearchBuilder.and("dataCenterId", volumeSearchBuilder.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+
+ if (keyword != null) {
+ volumeSearchBuilder.and().op("keywordName", volumeSearchBuilder.entity().getName(), SearchCriteria.Op.LIKE);
+ volumeSearchBuilder.or("keywordVolumeType", volumeSearchBuilder.entity().getVolumeType(), SearchCriteria.Op.LIKE);
+ volumeSearchBuilder.or("keywordState", volumeSearchBuilder.entity().getState(), SearchCriteria.Op.LIKE);
+ volumeSearchBuilder.cp();
+ }
+
+ StoragePoolVO poolVO = null;
if (storageId != null) {
- StoragePoolVO poolVO = storagePoolDao.findByUuid(storageId);
- if (poolVO.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
- sb.and("storageId", sb.entity().getPoolUuid(), SearchCriteria.Op.IN);
+ poolVO = storagePoolDao.findByUuid(storageId);
+ if (poolVO == null) {
+ throw new InvalidParameterValueException("Unable to find storage pool by uuid " + storageId);
+ } else if (poolVO.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
+ volumeSearchBuilder.and("storageId", volumeSearchBuilder.entity().getPoolId(), SearchCriteria.Op.IN);
} else {
- sb.and("storageId", sb.entity().getPoolUuid(), SearchCriteria.Op.EQ);
+ volumeSearchBuilder.and("storageId", volumeSearchBuilder.entity().getPoolId(), SearchCriteria.Op.EQ);
}
}
- sb.and("diskOfferingId", sb.entity().getDiskOfferingId(), SearchCriteria.Op.EQ);
- sb.and("display", sb.entity().isDisplayVolume(), SearchCriteria.Op.EQ);
- sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
- sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
+ if (clusterId != null || podId != null) {
+ SearchBuilder<StoragePoolVO> storagePoolSearch = storagePoolDao.createSearchBuilder();
+ storagePoolSearch.and("clusterId", storagePoolSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+ storagePoolSearch.and("podId", storagePoolSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+ volumeSearchBuilder.join("storagePoolSearch", storagePoolSearch, storagePoolSearch.entity().getId(), volumeSearchBuilder.entity().getPoolId(), JoinBuilder.JoinType.INNER);
+ }
+
+ volumeSearchBuilder.and("diskOfferingId", volumeSearchBuilder.entity().getDiskOfferingId(), SearchCriteria.Op.EQ);
+ volumeSearchBuilder.and("display", volumeSearchBuilder.entity().isDisplayVolume(), SearchCriteria.Op.EQ);
+ volumeSearchBuilder.and("state", volumeSearchBuilder.entity().getState(), SearchCriteria.Op.EQ);
+ volumeSearchBuilder.and("stateNEQ", volumeSearchBuilder.entity().getState(), SearchCriteria.Op.NEQ);
+
+ // Need to test thoroughly
if (!shouldListSystemVms) {
- sb.and().op("systemUse", sb.entity().isSystemUse(), SearchCriteria.Op.NEQ);
- sb.or("nulltype", sb.entity().isSystemUse(), SearchCriteria.Op.NULL);
- sb.cp();
+ SearchBuilder<VMInstanceVO> vmSearch = _vmInstanceDao.createSearchBuilder();
+ SearchBuilder<ServiceOfferingVO> serviceOfferingSearch = _srvOfferingDao.createSearchBuilder();
+ vmSearch.and().op("svmType", vmSearch.entity().getType(), SearchCriteria.Op.NIN);
+ vmSearch.or("vmSearchNulltype", vmSearch.entity().getType(), SearchCriteria.Op.NULL);
+ vmSearch.cp();
- sb.and().op("type", sb.entity().getVmType(), SearchCriteria.Op.NIN);
- sb.or("nulltype", sb.entity().getVmType(), SearchCriteria.Op.NULL);
- sb.cp();
+ serviceOfferingSearch.and().op("systemUse", serviceOfferingSearch.entity().isSystemUse(), SearchCriteria.Op.NEQ);
+ serviceOfferingSearch.or("serviceOfferingSearchNulltype", serviceOfferingSearch.entity().isSystemUse(), SearchCriteria.Op.NULL);
+ serviceOfferingSearch.cp();
+
+ vmSearch.join("serviceOfferingSearch", serviceOfferingSearch, serviceOfferingSearch.entity().getId(), vmSearch.entity().getServiceOfferingId(), JoinBuilder.JoinType.LEFT);
+
+ volumeSearchBuilder.join("vmSearch", vmSearch, vmSearch.entity().getId(), volumeSearchBuilder.entity().getInstanceId(), JoinBuilder.JoinType.LEFT);
+
+ }
+
+ if (MapUtils.isNotEmpty(tags)) {
+ SearchBuilder<ResourceTagVO> resourceTagSearch = resourceTagDao.createSearchBuilder();
+ resourceTagSearch.and("resourceType", resourceTagSearch.entity().getResourceType(), Op.EQ);
+ resourceTagSearch.and().op();
+ for (int count = 0; count < tags.size(); count++) {
+ if (count == 0) {
+ resourceTagSearch.op("tagKey" + count, resourceTagSearch.entity().getKey(), Op.EQ);
+ } else {
+ resourceTagSearch.or().op("tagKey" + count, resourceTagSearch.entity().getKey(), Op.EQ);
+ }
+ resourceTagSearch.and("tagValue" + count, resourceTagSearch.entity().getValue(), Op.EQ);
+ resourceTagSearch.cp();
+ }
+ resourceTagSearch.cp();
+
+ volumeSearchBuilder.join("tags", resourceTagSearch, resourceTagSearch.entity().getResourceId(), volumeSearchBuilder.entity().getId(), JoinBuilder.JoinType.INNER);
}
// now set the SC criteria...
- SearchCriteria<VolumeJoinVO> sc = sb.create();
- accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+ SearchCriteria<VolumeVO> sc = volumeSearchBuilder.create();
+ accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
if (keyword != null) {
- SearchCriteria<VolumeJoinVO> ssc = _volumeJoinDao.createSearchCriteria();
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+ sc.setParameters("keywordName", "%" + keyword + "%");
+ sc.setParameters("keywordVolumeType", "%" + keyword + "%");
+ sc.setParameters("keywordState", "%" + keyword + "%");
}
if (name != null) {
@@ -2426,19 +2525,18 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
setIdsListToSearchCriteria(sc, ids);
if (!shouldListSystemVms) {
- sc.setParameters("systemUse", 1);
- sc.setParameters("type", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter);
+ sc.setJoinParameters("vmSearch", "svmType", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter);
+ sc.getJoin("vmSearch").setJoinParameters("serviceOfferingSearch", "systemUse", 1);
}
- if (tags != null && !tags.isEmpty()) {
- SearchCriteria<VolumeJoinVO> tagSc = _volumeJoinDao.createSearchCriteria();
- for (String key : tags.keySet()) {
- SearchCriteria<VolumeJoinVO> tsc = _volumeJoinDao.createSearchCriteria();
- tsc.addAnd("tagKey", SearchCriteria.Op.EQ, key);
- tsc.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key));
- tagSc.addOr("tagKey", SearchCriteria.Op.SC, tsc);
+ if (MapUtils.isNotEmpty(tags)) {
+ int count = 0;
+ sc.setJoinParameters("tags", "resourceType", ResourceObjectType.Volume);
+ for (Map.Entry<String, String> entry : tags.entrySet()) {
+ sc.setJoinParameters("tags", "tagKey" + count, entry.getKey());
+ sc.setJoinParameters("tags", "tagValue" + count, entry.getValue());
+ count++;
}
- sc.addAnd("tagKey", SearchCriteria.Op.SC, tagSc);
}
if (diskOffId != null) {
@@ -2458,23 +2556,21 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
- if (podId != null) {
- sc.setParameters("podId", podId);
- }
if (storageId != null) {
- StoragePoolVO poolVO = storagePoolDao.findByUuid(storageId);
if (poolVO.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
- List<StoragePoolVO> childDatastores = storagePoolDao.listChildStoragePoolsInDatastoreCluster(poolVO.getId());
- List<String> childDatastoreIds = childDatastores.stream().map(mo -> mo.getUuid()).collect(Collectors.toList());
- sc.setParameters("storageId", childDatastoreIds.toArray());
+ List<StoragePoolVO> childDataStores = storagePoolDao.listChildStoragePoolsInDatastoreCluster(poolVO.getId());
+ sc.setParameters("storageId", childDataStores.stream().map(StoragePoolVO::getId).toArray());
} else {
- sc.setParameters("storageId", storageId);
+ sc.setParameters("storageId", poolVO.getId());
}
}
if (clusterId != null) {
- sc.setParameters("clusterId", clusterId);
+ sc.setJoinParameters("storagePoolSearch", "clusterId", clusterId);
+ }
+ if (podId != null) {
+ sc.setJoinParameters("storagePoolSearch", "podId", podId);
}
if (state != null) {
@@ -2484,20 +2580,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
// search Volume details by ids
- Pair<List<VolumeJoinVO>, Integer> uniqueVolPair = _volumeJoinDao.searchAndCount(sc, searchFilter);
+ Pair<List<VolumeVO>, Integer> uniqueVolPair = volumeDao.searchAndCount(sc, searchFilter);
Integer count = uniqueVolPair.second();
- if (count.intValue() == 0) {
- // empty result
- return uniqueVolPair;
- }
- List<VolumeJoinVO> uniqueVols = uniqueVolPair.first();
- Long[] vrIds = new Long[uniqueVols.size()];
- int i = 0;
- for (VolumeJoinVO v : uniqueVols) {
- vrIds[i++] = v.getId();
- }
- List<VolumeJoinVO> vrs = _volumeJoinDao.searchByIds(vrIds);
- return new Pair<List<VolumeJoinVO>, Integer>(vrs, count);
+ List<Long> vmIds = uniqueVolPair.first().stream().map(VolumeVO::getId).collect(Collectors.toList());
+ return new Pair<>(vmIds, count);
}
private boolean shouldListSystemVms(ListVolumesCmd cmd, Long callerId) {
@@ -2520,6 +2606,20 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
private Pair<List<DomainJoinVO>, Integer> searchForDomainsInternal(ListDomainsCmd cmd) {
+ Pair<List<Long>, Integer> domainIdPage = searchForDomainIdsAndCount(cmd);
+
+ Integer count = domainIdPage.second();
+ Long[] idArray = domainIdPage.first().toArray(new Long[0]);
+
+ if (count == 0) {
+ return new Pair<>(new ArrayList<>(), count);
+ }
+
+ List<DomainJoinVO> domains = _domainJoinDao.searchByIds(idArray);
+ return new Pair<>(domains, count);
+ }
+
+ private Pair<List<Long>, Integer> searchForDomainIdsAndCount(ListDomainsCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
Long domainId = cmd.getId();
boolean listAll = cmd.listAll();
@@ -2541,24 +2641,27 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
}
- Filter searchFilter = new Filter(DomainJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+ Filter searchFilter = new Filter(DomainVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
String domainName = cmd.getDomainName();
Integer level = cmd.getLevel();
Object keyword = cmd.getKeyword();
- SearchBuilder<DomainJoinVO> sb = _domainJoinDao.createSearchBuilder();
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
- sb.and("level", sb.entity().getLevel(), SearchCriteria.Op.EQ);
- sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE);
- sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+ SearchBuilder<DomainVO> domainSearchBuilder = _domainDao.createSearchBuilder();
+ domainSearchBuilder.select(null, Func.DISTINCT, domainSearchBuilder.entity().getId()); // select distinct
+ domainSearchBuilder.and("id", domainSearchBuilder.entity().getId(), SearchCriteria.Op.EQ);
+ domainSearchBuilder.and("name", domainSearchBuilder.entity().getName(), SearchCriteria.Op.EQ);
+ domainSearchBuilder.and("level", domainSearchBuilder.entity().getLevel(), SearchCriteria.Op.EQ);
+ domainSearchBuilder.and("path", domainSearchBuilder.entity().getPath(), SearchCriteria.Op.LIKE);
+ domainSearchBuilder.and("state", domainSearchBuilder.entity().getState(), SearchCriteria.Op.EQ);
- SearchCriteria<DomainJoinVO> sc = sb.create();
+ if (keyword != null) {
+ domainSearchBuilder.and("keywordName", domainSearchBuilder.entity().getName(), SearchCriteria.Op.LIKE);
+ }
+
+ SearchCriteria<DomainVO> sc = domainSearchBuilder.create();
if (keyword != null) {
- SearchCriteria<DomainJoinVO> ssc = _domainJoinDao.createSearchCriteria();
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+ sc.setParameters("keywordName", "%" + keyword + "%");
}
if (domainName != null) {
@@ -2583,7 +2686,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
// return only Active domains to the API
sc.setParameters("state", Domain.State.Active);
- return _domainJoinDao.searchAndCount(sc, searchFilter);
+ Pair<List<DomainVO>, Integer> uniqueDomainPair = _domainDao.searchAndCount(sc, searchFilter);
+ Integer count = uniqueDomainPair.second();
+ List<Long> domainIds = uniqueDomainPair.first().stream().map(DomainVO::getId).collect(Collectors.toList());
+ return new Pair<>(domainIds, count);
}
@Override
@@ -2602,6 +2708,21 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
private Pair<List<AccountJoinVO>, Integer> searchForAccountsInternal(ListAccountsCmd cmd) {
+
+ Pair<List<Long>, Integer> accountIdPage = searchForAccountIdsAndCount(cmd);
+
+ Integer count = accountIdPage.second();
+ Long[] idArray = accountIdPage.first().toArray(new Long[0]);
+
+ if (count == 0) {
+ return new Pair<>(new ArrayList<>(), count);
+ }
+
+ List<AccountJoinVO> accounts = _accountJoinDao.searchByIds(idArray);
+ return new Pair<>(accounts, count);
+ }
+
+ private Pair<List<Long>, Integer> searchForAccountIdsAndCount(ListAccountsCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
Long domainId = cmd.getDomainId();
Long accountId = cmd.getId();
@@ -2657,29 +2778,38 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
accountMgr.checkAccess(caller, null, true, account);
}
- Filter searchFilter = new Filter(AccountJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+ Filter searchFilter = new Filter(AccountVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
Object type = cmd.getAccountType();
Object state = cmd.getState();
Object isCleanupRequired = cmd.isCleanupRequired();
Object keyword = cmd.getKeyword();
- SearchBuilder<AccountJoinVO> sb = _accountJoinDao.createSearchBuilder();
- sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.EQ);
- sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
- sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
- sb.and("needsCleanup", sb.entity().isNeedsCleanup(), SearchCriteria.Op.EQ);
- sb.and("typeNEQ", sb.entity().getType(), SearchCriteria.Op.NEQ);
- sb.and("idNEQ", sb.entity().getId(), SearchCriteria.Op.NEQ);
- sb.and("type2NEQ", sb.entity().getType(), SearchCriteria.Op.NEQ);
+ SearchBuilder<AccountVO> accountSearchBuilder = _accountDao.createSearchBuilder();
+ accountSearchBuilder.select(null, Func.DISTINCT, accountSearchBuilder.entity().getId()); // select distinct
+ accountSearchBuilder.and("accountName", accountSearchBuilder.entity().getAccountName(), SearchCriteria.Op.EQ);
+ accountSearchBuilder.and("domainId", accountSearchBuilder.entity().getDomainId(), SearchCriteria.Op.EQ);
+ accountSearchBuilder.and("id", accountSearchBuilder.entity().getId(), SearchCriteria.Op.EQ);
+ accountSearchBuilder.and("type", accountSearchBuilder.entity().getType(), SearchCriteria.Op.EQ);
+ accountSearchBuilder.and("state", accountSearchBuilder.entity().getState(), SearchCriteria.Op.EQ);
+ accountSearchBuilder.and("needsCleanup", accountSearchBuilder.entity().getNeedsCleanup(), SearchCriteria.Op.EQ);
+ accountSearchBuilder.and("typeNEQ", accountSearchBuilder.entity().getType(), SearchCriteria.Op.NEQ);
+ accountSearchBuilder.and("idNEQ", accountSearchBuilder.entity().getId(), SearchCriteria.Op.NEQ);
+ accountSearchBuilder.and("type2NEQ", accountSearchBuilder.entity().getType(), SearchCriteria.Op.NEQ);
if (domainId != null && isRecursive) {
- sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+ SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
+ domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
+ accountSearchBuilder.join("domainSearch", domainSearch, domainSearch.entity().getId(), accountSearchBuilder.entity().getDomainId(), JoinBuilder.JoinType.INNER);
}
- SearchCriteria<AccountJoinVO> sc = sb.create();
+ if (keyword != null) {
+ accountSearchBuilder.and().op("keywordAccountName", accountSearchBuilder.entity().getAccountName(), SearchCriteria.Op.LIKE);
+ accountSearchBuilder.or("keywordState", accountSearchBuilder.entity().getState(), SearchCriteria.Op.LIKE);
+ accountSearchBuilder.cp();
+ }
+
+ SearchCriteria<AccountVO> sc = accountSearchBuilder.create();
// don't return account of type project to the end user
sc.setParameters("typeNEQ", Account.Type.PROJECT);
@@ -2693,10 +2823,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
if (keyword != null) {
- SearchCriteria<AccountJoinVO> ssc = _accountJoinDao.createSearchCriteria();
- ssc.addOr("accountName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- sc.addAnd("accountName", SearchCriteria.Op.SC, ssc);
+ sc.setParameters("keywordAccountName", "%" + keyword + "%");
+ sc.setParameters("keywordState", "%" + keyword + "%");
}
if (type != null) {
@@ -2725,13 +2853,16 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
if (domain == null) {
domain = _domainDao.findById(domainId);
}
- sc.setParameters("path", domain.getPath() + "%");
+ sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
} else {
sc.setParameters("domainId", domainId);
}
}
- return _accountJoinDao.searchAndCount(sc, searchFilter);
+ Pair<List<AccountVO>, Integer> uniqueAccountPair = _accountDao.searchAndCount(sc, searchFilter);
+ Integer count = uniqueAccountPair.second();
+ List<Long> accountIds = uniqueAccountPair.first().stream().map(AccountVO::getId).collect(Collectors.toList());
+ return new Pair<>(accountIds, count);
}
@Override
@@ -2846,6 +2977,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
ListResponse<StoragePoolResponse> response = new ListResponse<>();
List<StoragePoolResponse> poolResponses = ViewResponseHelper.createStoragePoolResponse(storagePools.first().toArray(new StoragePoolJoinVO[storagePools.first().size()]));
+ Map<String, Long> poolUuidToIdMap = storagePools.first().stream().collect(Collectors.toMap(StoragePoolJoinVO::getUuid, StoragePoolJoinVO::getId));
for (StoragePoolResponse poolResponse : poolResponses) {
DataStore store = dataStoreManager.getPrimaryDataStore(poolResponse.getId());
if (store != null) {
@@ -2854,8 +2986,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Map<String, String> caps = driver.getCapabilities();
if (Storage.StoragePoolType.NetworkFilesystem.toString().equals(poolResponse.getType()) &&
HypervisorType.VMware.toString().equals(poolResponse.getHypervisor())) {
- StoragePoolVO pool = storagePoolDao.findPoolByUUID(poolResponse.getId());
- StoragePoolDetailVO detail = _storagePoolDetailsDao.findDetail(pool.getId(), Storage.Capability.HARDWARE_ACCELERATION.toString());
+ StoragePoolDetailVO detail = _storagePoolDetailsDao.findDetail(poolUuidToIdMap.get(poolResponse.getId()), Storage.Capability.HARDWARE_ACCELERATION.toString());
if (detail != null) {
caps.put(Storage.Capability.HARDWARE_ACCELERATION.toString(), detail.getValue());
}
@@ -2885,26 +3016,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Long startIndex = cmd.getStartIndex();
Long pageSize = cmd.getPageSizeVal();
- Filter searchFilter = new Filter(StoragePoolJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+ Filter searchFilter = new Filter(StoragePoolVO.class, "id", Boolean.TRUE, startIndex, pageSize);
- // search & count Pool details by ids
- Pair<List<StoragePoolJoinVO>, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(id, name, zoneId, path, pod,
+ Pair<List<Long>, Integer> uniquePoolPair = storagePoolDao.searchForIdsAndCount(id, name, zoneId, path, pod,
cluster, address, scopeType, status, keyword, searchFilter);
- Integer count = uniquePoolPair.second();
- if (count.intValue() == 0) {
- // empty result
- return uniquePoolPair;
- }
- List<StoragePoolJoinVO> uniquePools = uniquePoolPair.first();
- Long[] vrIds = new Long[uniquePools.size()];
- int i = 0;
- for (StoragePoolJoinVO v : uniquePools) {
- vrIds[i++] = v.getId();
- }
- List<StoragePoolJoinVO> vrs = _poolJoinDao.searchByIds(vrIds);
- return new Pair<List<StoragePoolJoinVO>, Integer>(vrs, count);
+ List<StoragePoolJoinVO> storagePools = _poolJoinDao.searchByIds(uniquePoolPair.first().toArray(new Long[0]));
+ return new Pair<>(storagePools, uniquePoolPair.second());
}
@Override
@@ -3162,6 +3281,33 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
private Pair<List<DiskOfferingJoinVO>, Integer> searchForDiskOfferingsInternal(ListDiskOfferingsCmd cmd) {
+ Ternary<List<Long>, Integer, String[]> diskOfferingIdPage = searchForDiskOfferingsIdsAndCount(cmd);
+
+ Integer count = diskOfferingIdPage.second();
+ Long[] idArray = diskOfferingIdPage.first().toArray(new Long[0]);
+ String[] requiredTagsArray = diskOfferingIdPage.third();
+
+ if (count == 0) {
+ return new Pair<>(new ArrayList<>(), count);
+ }
+
+ List<DiskOfferingJoinVO> diskOfferings = _diskOfferingJoinDao.searchByIds(idArray);
+
+ if (requiredTagsArray.length != 0) {
+ ListIterator<DiskOfferingJoinVO> iteratorForTagsChecking = diskOfferings.listIterator();
+ while (iteratorForTagsChecking.hasNext()) {
+ DiskOfferingJoinVO offering = iteratorForTagsChecking.next();
+ String offeringTags = offering.getTags();
+ String[] offeringTagsArray = (offeringTags == null || offeringTags.isEmpty()) ? new String[0] : offeringTags.split(",");
+ if (!CollectionUtils.isSubCollection(Arrays.asList(requiredTagsArray), Arrays.asList(offeringTagsArray))) {
+ iteratorForTagsChecking.remove();
+ }
+ }
+ }
+ return new Pair<>(diskOfferings, count);
+ }
+
+ private Ternary<List<Long>, Integer, String[]> searchForDiskOfferingsIdsAndCount(ListDiskOfferingsCmd cmd) {
// Note
// The list method for offerings is being modified in accordance with
// discussion with Will/Kevin
@@ -3172,11 +3318,6 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
// till
// root
- Filter searchFilter = new Filter(DiskOfferingJoinVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
- searchFilter.addOrderBy(DiskOfferingJoinVO.class, "id", true);
- SearchCriteria<DiskOfferingJoinVO> sc = _diskOfferingJoinDao.createSearchCriteria();
- sc.addAnd("computeOnly", Op.EQ, false);
-
Account account = CallContext.current().getCallingAccount();
Object name = cmd.getDiskOfferingName();
Object id = cmd.getId();
@@ -3192,18 +3333,41 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Boolean encrypt = cmd.getEncrypt();
String storageType = cmd.getStorageType();
+ Filter searchFilter = new Filter(DiskOfferingVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
+ searchFilter.addOrderBy(DiskOfferingVO.class, "id", true);
+ SearchBuilder<DiskOfferingVO> diskOfferingSearch = _diskOfferingDao.createSearchBuilder();
+ diskOfferingSearch.select(null, Func.DISTINCT, diskOfferingSearch.entity().getId()); // select distinct
+
+ diskOfferingSearch.and("computeOnly", diskOfferingSearch.entity().isComputeOnly(), Op.EQ);
+ diskOfferingSearch.and("activeState", diskOfferingSearch.entity().getState(), Op.EQ);
+
// Keeping this logic consistent with domain specific zones
// if a domainId is provided, we just return the disk offering
// associated with this domain
- if (domainId != null) {
+ if (domainId != null && accountName == null) {
if (accountMgr.isRootAdmin(account.getId()) || isPermissible(account.getDomainId(), domainId)) {
// check if the user's domain == do's domain || user's domain is
// a child of so's domain for non-root users
- sc.addAnd("domainId", Op.FIND_IN_SET, String.valueOf(domainId));
+ SearchBuilder<DiskOfferingDetailVO> domainDetailsSearch = _diskOfferingDetailsDao.createSearchBuilder();
+ domainDetailsSearch.and("domainId", domainDetailsSearch.entity().getValue(), Op.EQ);
+
+ diskOfferingSearch.join("domainDetailsSearch", domainDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ diskOfferingSearch.entity().getId(), domainDetailsSearch.entity().getResourceId(),
+ domainDetailsSearch.entity().getName(), diskOfferingSearch.entity().setString(ApiConstants.DOMAIN_ID));
+
if (!isRootAdmin) {
- sc.addAnd("displayOffering", SearchCriteria.Op.EQ, 1);
+ diskOfferingSearch.and("displayOffering", diskOfferingSearch.entity().getDisplayOffering(), Op.EQ);
}
- return _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
+
+ SearchCriteria<DiskOfferingVO> sc = diskOfferingSearch.create();
+ sc.setParameters("computeOnly", false);
+ sc.setParameters("activeState", DiskOffering.State.Active);
+
+ sc.setJoinParameters("domainDetailsSearch", "domainId", domainId);
+
+ Pair<List<DiskOfferingVO>, Integer> uniquePairs = _diskOfferingDao.searchAndCount(sc, searchFilter);
+ List<Long> idsArray = uniquePairs.first().stream().map(DiskOfferingVO::getId).collect(Collectors.toList());
+ return new Ternary<>(idsArray, uniquePairs.second(), new String[0]);
} else {
throw new PermissionDeniedException("The account:" + account.getAccountName() + " does not fall in the same domain hierarchy as the disk offering");
}
@@ -3224,104 +3388,136 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
if (keyword != null) {
- SearchCriteria<DiskOfferingJoinVO> ssc = _diskOfferingJoinDao.createSearchCriteria();
- ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+ diskOfferingSearch.and().op("keywordDisplayText", diskOfferingSearch.entity().getDisplayText(), Op.LIKE);
+ diskOfferingSearch.or("keywordName", diskOfferingSearch.entity().getName(), Op.LIKE);
+ diskOfferingSearch.cp();
}
if (id != null) {
- sc.addAnd("id", SearchCriteria.Op.EQ, id);
+ diskOfferingSearch.and("id", diskOfferingSearch.entity().getId(), Op.EQ);
}
if (name != null) {
- sc.addAnd("name", SearchCriteria.Op.EQ, name);
+ diskOfferingSearch.and("name", diskOfferingSearch.entity().getName(), Op.EQ);
}
if (encrypt != null) {
- sc.addAnd("encrypt", SearchCriteria.Op.EQ, encrypt);
+ diskOfferingSearch.and("encrypt", diskOfferingSearch.entity().getEncrypt(), Op.EQ);
}
- useStorageType(sc, storageType);
+ if (storageType != null || zoneId != null) {
+ diskOfferingSearch.and("useLocalStorage", diskOfferingSearch.entity().isUseLocalStorage(), Op.EQ);
+ }
if (zoneId != null) {
- SearchBuilder<DiskOfferingJoinVO> sb = _diskOfferingJoinDao.createSearchBuilder();
- sb.and("zoneId", sb.entity().getZoneId(), Op.FIND_IN_SET);
- sb.or("zId", sb.entity().getZoneId(), Op.NULL);
- sb.done();
- SearchCriteria<DiskOfferingJoinVO> zoneSC = sb.create();
- zoneSC.setParameters("zoneId", String.valueOf(zoneId));
- sc.addAnd("zoneId", SearchCriteria.Op.SC, zoneSC);
- DataCenterJoinVO zone = _dcJoinDao.findById(zoneId);
- if (DataCenter.Type.Edge.equals(zone.getType())) {
- sc.addAnd("useLocalStorage", Op.EQ, true);
- }
+ SearchBuilder<DiskOfferingDetailVO> zoneDetailSearch = _diskOfferingDetailsDao.createSearchBuilder();
+ zoneDetailSearch.and().op("zoneId", zoneDetailSearch.entity().getValue(), Op.EQ);
+ zoneDetailSearch.or("zoneIdNull", zoneDetailSearch.entity().getId(), Op.NULL);
+ zoneDetailSearch.cp();
+
+ diskOfferingSearch.join("zoneDetailSearch", zoneDetailSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ diskOfferingSearch.entity().getId(), zoneDetailSearch.entity().getResourceId(),
+ zoneDetailSearch.entity().getName(), diskOfferingSearch.entity().setString(ApiConstants.ZONE_ID));
}
DiskOffering currentDiskOffering = null;
+ Volume volume = null;
if (volumeId != null) {
- Volume volume = volumeDao.findById(volumeId);
+ volume = volumeDao.findById(volumeId);
if (volume == null) {
throw new InvalidParameterValueException(String.format("Unable to find a volume with specified id %s", volumeId));
}
currentDiskOffering = _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId());
if (!currentDiskOffering.isComputeOnly() && currentDiskOffering.getDiskSizeStrictness()) {
- SearchCriteria<DiskOfferingJoinVO> ssc = _diskOfferingJoinDao.createSearchCriteria();
- ssc.addOr("diskSize", Op.EQ, volume.getSize());
- ssc.addOr("customized", SearchCriteria.Op.EQ, true);
- sc.addAnd("diskSizeOrCustomized", SearchCriteria.Op.SC, ssc);
+ diskOfferingSearch.and().op("diskSize", diskOfferingSearch.entity().getDiskSize(), Op.EQ);
+ diskOfferingSearch.or("customized", diskOfferingSearch.entity().isCustomized(), Op.EQ);
+ diskOfferingSearch.cp();
}
- sc.addAnd("id", SearchCriteria.Op.NEQ, currentDiskOffering.getId());
- sc.addAnd("diskSizeStrictness", Op.EQ, currentDiskOffering.getDiskSizeStrictness());
+ diskOfferingSearch.and("idNEQ", diskOfferingSearch.entity().getId(), Op.NEQ);
+ diskOfferingSearch.and("diskSizeStrictness", diskOfferingSearch.entity().getDiskSizeStrictness(), Op.EQ);
}
- // Filter offerings that are not associated with caller's domain
- // Fetch the offering ids from the details table since theres no smart way to filter them in the join ... yet!
account = accountMgr.finalizeOwner(account, accountName, domainId, projectId);
if (!Account.Type.ADMIN.equals(account.getType())) {
- Domain callerDomain = _domainDao.findById(account.getDomainId());
- List<Long> domainIds = findRelatedDomainIds(callerDomain, isRecursive);
+ SearchBuilder<DiskOfferingDetailVO> domainDetailsSearch = _diskOfferingDetailsDao.createSearchBuilder();
+ domainDetailsSearch.and().op("domainIdIN", domainDetailsSearch.entity().getValue(), Op.IN);
+ domainDetailsSearch.or("domainIdNull", domainDetailsSearch.entity().getId(), Op.NULL);
+ domainDetailsSearch.cp();
+
+ diskOfferingSearch.join("domainDetailsSearch", domainDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ diskOfferingSearch.entity().getId(), domainDetailsSearch.entity().getResourceId(),
+ domainDetailsSearch.entity().getName(), diskOfferingSearch.entity().setString(ApiConstants.DOMAIN_ID));
+ }
+
+ SearchCriteria<DiskOfferingVO> sc = diskOfferingSearch.create();
- List<Long> ids = _diskOfferingDetailsDao.findOfferingIdsByDomainIds(domainIds);
- SearchBuilder<DiskOfferingJoinVO> sb = _diskOfferingJoinDao.createSearchBuilder();
- if (ids != null && !ids.isEmpty()) {
- sb.and("id", sb.entity().getId(), Op.IN);
+ sc.setParameters("computeOnly", false);
+ sc.setParameters("activeState", DiskOffering.State.Active);
+
+ if (keyword != null) {
+ sc.setParameters("keywordDisplayText", "%" + keyword + "%");
+ sc.setParameters("keywordName", "%" + keyword + "%");
+ }
+
+ if (id != null) {
+ sc.setParameters("id", id);
+ }
+
+ if (name != null) {
+ sc.setParameters("name", name);
+ }
+
+ if (encrypt != null) {
+ sc.setParameters("encrypt", encrypt);
+ }
+
+ if (storageType != null) {
+ if (storageType.equalsIgnoreCase(ServiceOffering.StorageType.local.toString())) {
+ sc.setParameters("useLocalStorage", true);
+
+ } else if (storageType.equalsIgnoreCase(ServiceOffering.StorageType.shared.toString())) {
+ sc.setParameters("useLocalStorage", false);
+ }
+ }
+
+ if (zoneId != null) {
+ sc.setJoinParameters("zoneDetailSearch", "zoneId", zoneId);
+
+ DataCenterJoinVO zone = _dcJoinDao.findById(zoneId);
+ if (DataCenter.Type.Edge.equals(zone.getType())) {
+ sc.setParameters("useLocalStorage", true);
}
- sb.or("domainId", sb.entity().getDomainId(), Op.NULL);
- sb.done();
+ }
- SearchCriteria<DiskOfferingJoinVO> scc = sb.create();
- if (ids != null && !ids.isEmpty()) {
- scc.setParameters("id", ids.toArray());
+ if (volumeId != null) {
+ if (!currentDiskOffering.isComputeOnly() && currentDiskOffering.getDiskSizeStrictness()) {
+ sc.setParameters("diskSize", volume.getSize());
+ sc.setParameters("customized", true);
}
- sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
+ sc.setParameters("idNEQ", currentDiskOffering.getId());
+ sc.setParameters("diskSizeStrictness", currentDiskOffering.getDiskSizeStrictness());
}
- Pair<List<DiskOfferingJoinVO>, Integer> result = _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
+ // Filter offerings that are not associated with caller's domain
+ if (!Account.Type.ADMIN.equals(account.getType())) {
+ Domain callerDomain = _domainDao.findById(account.getDomainId());
+ List<Long> domainIds = findRelatedDomainIds(callerDomain, isRecursive);
+
+ sc.setJoinParameters("domainDetailsSearch", "domainIdIN", domainIds.toArray());
+ }
+
+ Pair<List<DiskOfferingVO>, Integer> uniquePairs = _diskOfferingDao.searchAndCount(sc, searchFilter);
String[] requiredTagsArray = new String[0];
- if (CollectionUtils.isNotEmpty(result.first()) && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(zoneId)) {
+ if (CollectionUtils.isNotEmpty(uniquePairs.first()) && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(zoneId)) {
if (volumeId != null) {
- Volume volume = volumeDao.findById(volumeId);
- currentDiskOffering = _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId());
requiredTagsArray = currentDiskOffering.getTagsArray();
} else if (storagePoolId != null) {
requiredTagsArray = _storageTagDao.getStoragePoolTags(storagePoolId).toArray(new String[0]);
}
}
- if (requiredTagsArray.length != 0) {
- ListIterator<DiskOfferingJoinVO> iteratorForTagsChecking = result.first().listIterator();
- while (iteratorForTagsChecking.hasNext()) {
- DiskOfferingJoinVO offering = iteratorForTagsChecking.next();
- String offeringTags = offering.getTags();
- String[] offeringTagsArray = (offeringTags == null || offeringTags.isEmpty()) ? new String[0] : offeringTags.split(",");
- if (!CollectionUtils.isSubCollection(Arrays.asList(requiredTagsArray), Arrays.asList(offeringTagsArray))) {
- iteratorForTagsChecking.remove();
- }
- }
- }
+ List<Long> idsArray = uniquePairs.first().stream().map(DiskOfferingVO::getId).collect(Collectors.toList());
- return new Pair<>(result.first(), result.second());
+ return new Ternary<>(idsArray, uniquePairs.second(), requiredTagsArray);
}
private void useStorageType(SearchCriteria<?> sc, String storageType) {
@@ -3357,6 +3553,20 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInternal(ListServiceOfferingsCmd cmd) {
+ Pair<List<Long>, Integer> offeringIdPage = searchForServiceOfferingIdsAndCount(cmd);
+
+ Integer count = offeringIdPage.second();
+ Long[] idArray = offeringIdPage.first().toArray(new Long[0]);
+
+ if (count == 0) {
+ return new Pair<>(new ArrayList<>(), count);
+ }
+
+ List<ServiceOfferingJoinVO> srvOfferings = _srvOfferingJoinDao.searchByIds(idArray);
+ return new Pair<>(srvOfferings, count);
+ }
+
+ private Pair<List<Long>, Integer> searchForServiceOfferingIdsAndCount(ListServiceOfferingsCmd cmd) {
// Note
// The filteredOfferings method for offerings is being modified in accordance with
// discussion with Will/Kevin
@@ -3366,9 +3576,6 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
// their domains+parent domains ... all the way
// till
// root
- Filter searchFilter = new Filter(ServiceOfferingJoinVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
- searchFilter.addOrderBy(ServiceOfferingJoinVO.class, "id", true);
-
Account caller = CallContext.current().getCallingAccount();
Long projectId = cmd.getProjectId();
String accountName = cmd.getAccountName();
@@ -3380,6 +3587,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Boolean isSystem = cmd.getIsSystem();
String vmTypeStr = cmd.getSystemVmType();
ServiceOfferingVO currentVmOffering = null;
+ DiskOfferingVO diskOffering = null;
Boolean isRecursive = cmd.isRecursive();
Long zoneId = cmd.getZoneId();
Integer cpuNumber = cmd.getCpuNumber();
@@ -3389,9 +3597,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
String storageType = cmd.getStorageType();
final Account owner = accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
- SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
+
if (!accountMgr.isRootAdmin(caller.getId()) && isSystem) {
- throw new InvalidParameterValueException("Only ROOT admins can access system's offering");
+ throw new InvalidParameterValueException("Only ROOT admins can access system offerings.");
}
// Keeping this logic consistent with domain specific zones
@@ -3405,34 +3613,37 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
}
}
+ VMInstanceVO vmInstance = null;
if (vmId != null) {
- VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+ vmInstance = _vmInstanceDao.findById(vmId);
if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id");
ex.addProxyObject(vmId.toString(), "vmId");
throw ex;
}
+ accountMgr.checkAccess(owner, null, true, vmInstance);
+ }
+
+ Filter searchFilter = new Filter(ServiceOfferingVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
+ searchFilter.addOrderBy(ServiceOfferingVO.class, "id", true);
- accountMgr.checkAccess(caller, null, true, vmInstance);
+ SearchBuilder<ServiceOfferingVO> serviceOfferingSearch = _srvOfferingDao.createSearchBuilder();
+ serviceOfferingSearch.select(null, Func.DISTINCT, serviceOfferingSearch.entity().getId()); // select distinct
+ serviceOfferingSearch.and("activeState", serviceOfferingSearch.entity().getState(), Op.EQ);
+ if (vmId != null) {
currentVmOffering = _srvOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
- if (! currentVmOffering.isDynamic()) {
- sc.addAnd("id", SearchCriteria.Op.NEQ, currentVmOffering.getId());
+ diskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentVmOffering.getDiskOfferingId());
+ if (!currentVmOffering.isDynamic()) {
+ serviceOfferingSearch.and("idNEQ", serviceOfferingSearch.entity().getId(), SearchCriteria.Op.NEQ);
}
if (currentVmOffering.getDiskOfferingStrictness()) {
- sc.addAnd("diskOfferingId", Op.EQ, currentVmOffering.getDiskOfferingId());
- sc.addAnd("diskOfferingStrictness", Op.EQ, true);
- } else {
- sc.addAnd("diskOfferingStrictness", Op.EQ, false);
+ serviceOfferingSearch.and("diskOfferingId", serviceOfferingSearch.entity().getDiskOfferingId(), SearchCriteria.Op.EQ);
}
+ serviceOfferingSearch.and("diskOfferingStrictness", serviceOfferingSearch.entity().getDiskOfferingStrictness(), SearchCriteria.Op.EQ);
- boolean isRootVolumeUsingLocalStorage = virtualMachineManager.isRootVolumeOnLocalStorage(vmId);
-
- // 1. Only return offerings with the same storage type than the storage pool where the VM's root volume is allocated
- sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, isRootVolumeUsingLocalStorage);
-
- // 2.In case vm is running return only offerings greater than equal to current offering compute and offering's dynamic scalability should match
+ // In case vm is running return only offerings greater than equal to current offering compute and offering's dynamic scalability should match
if (vmInstance.getState() == VirtualMachine.State.Running) {
Integer vmCpu = currentVmOffering.getCpu();
Integer vmMemory = currentVmOffering.getRamSize();
@@ -3448,20 +3659,58 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
vmMemory = NumbersUtil.parseInt(details.get(ApiConstants.MEMORY), 0);
}
if (vmCpu != null && vmCpu > 0) {
- sc.addAnd("cpu", Op.SC, getMinimumCpuServiceOfferingJoinSearchCriteria(vmCpu));
+ /*
+ (service_offering.cpu >= ?)
+ OR (
+ service_offering.cpu IS NULL
+ AND (maxComputeDetailsSearch.value IS NULL OR maxComputeDetailsSearch.value >= ?)
+ )
+ */
+ SearchBuilder<ServiceOfferingDetailsVO> maxComputeDetailsSearch = _srvOfferingDetailsDao.createSearchBuilder();
+
+ serviceOfferingSearch.join("maxComputeDetailsSearch", maxComputeDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), maxComputeDetailsSearch.entity().getResourceId(),
+ maxComputeDetailsSearch.entity().getName(), serviceOfferingSearch.entity().setString(ApiConstants.MAX_CPU_NUMBER));
+
+ serviceOfferingSearch.and().op("vmCpu", serviceOfferingSearch.entity().getCpu(), Op.GTEQ);
+ serviceOfferingSearch.or().op("vmCpuNull", serviceOfferingSearch.entity().getCpu(), Op.NULL);
+ serviceOfferingSearch.and().op("maxComputeDetailsSearch", "vmMaxComputeNull", maxComputeDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.or("maxComputeDetailsSearch", "vmMaxComputeGTEQ", maxComputeDetailsSearch.entity().getValue(), Op.GTEQ).cp();
+
+ serviceOfferingSearch.cp().cp();
+
}
if (vmSpeed != null && vmSpeed > 0) {
- sc.addAnd("speed", Op.SC, getMinimumCpuSpeedServiceOfferingJoinSearchCriteria(vmSpeed));
+ serviceOfferingSearch.and().op("speedNULL", serviceOfferingSearch.entity().getSpeed(), Op.NULL);
+ serviceOfferingSearch.or("speedGTEQ", serviceOfferingSearch.entity().getSpeed(), Op.GTEQ);
+ serviceOfferingSearch.cp();
}
if (vmMemory != null && vmMemory > 0) {
- sc.addAnd("ramSize", Op.SC, getMinimumMemoryServiceOfferingJoinSearchCriteria(vmMemory));
+ /*
+ (service_offering.ram_size >= ?)
+ OR (
+ service_offering.ram_size IS NULL
+ AND (max_memory_details.value IS NULL OR max_memory_details.value >= ?)
+ )
+ */
+ SearchBuilder<ServiceOfferingDetailsVO> maxMemoryDetailsSearch = _srvOfferingDetailsDao.createSearchBuilder();
+
+ serviceOfferingSearch.join("maxMemoryDetailsSearch", maxMemoryDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), maxMemoryDetailsSearch.entity().getResourceId(),
+ maxMemoryDetailsSearch.entity().getName(), serviceOfferingSearch.entity().setString("maxmemory"));
+
+ serviceOfferingSearch.and().op("vmMemory", serviceOfferingSearch.entity().getRamSize(), Op.GTEQ);
+ serviceOfferingSearch.or().op("vmMemoryNull", serviceOfferingSearch.entity().getRamSize(), Op.NULL);
+ serviceOfferingSearch.and().op("maxMemoryDetailsSearch", "vmMaxMemoryNull", maxMemoryDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("maxMemoryDetailsSearch", "vmMaxMemoryGTEQ", maxMemoryDetailsSearch.entity().getValue(), Op.GTEQ).cp();
+
+ serviceOfferingSearch.cp().cp();
}
- sc.addAnd("dynamicScalingEnabled", Op.EQ, currentVmOffering.isDynamicScalingEnabled());
+ serviceOfferingSearch.and("dynamicScalingEnabled", serviceOfferingSearch.entity().isDynamicScalingEnabled(), SearchCriteria.Op.EQ);
}
}
- // boolean includePublicOfferings = false;
- if ((accountMgr.isNormalUser(caller.getId()) || accountMgr.isDomainAdmin(caller.getId())) || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) {
+ if ((accountMgr.isNormalUser(owner.getId()) || accountMgr.isDomainAdmin(owner.getId())) || owner.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) {
// For non-root users.
if (isSystem) {
throw new InvalidParameterValueException("Only root admins can access system's offering");
@@ -3474,152 +3723,325 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
} else {
// for root users
if (owner.getDomainId() != 1 && isSystem) { // NON ROOT admin
- throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering.");
+ throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering");
}
if (domainId != null && accountName == null) {
- sc.addAnd("domainId", Op.FIND_IN_SET, String.valueOf(domainId));
+ SearchBuilder<ServiceOfferingDetailsVO> srvOffrDomainDetailSearch = _srvOfferingDetailsDao.createSearchBuilder();
+ srvOffrDomainDetailSearch.and("domainId", srvOffrDomainDetailSearch.entity().getValue(), Op.EQ);
+ serviceOfferingSearch.join("domainDetailSearch", srvOffrDomainDetailSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), srvOffrDomainDetailSearch.entity().getResourceId(),
+ srvOffrDomainDetailSearch.entity().getName(), serviceOfferingSearch.entity().setString(ApiConstants.DOMAIN_ID));
}
}
if (keyword != null) {
- SearchCriteria<ServiceOfferingJoinVO> ssc = _srvOfferingJoinDao.createSearchCriteria();
- ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+ serviceOfferingSearch.and().op("keywordName", serviceOfferingSearch.entity().getName(), SearchCriteria.Op.LIKE);
+ serviceOfferingSearch.or("keywordDisplayText", serviceOfferingSearch.entity().getDisplayText(), SearchCriteria.Op.LIKE);
+ serviceOfferingSearch.cp();
+ }
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+ if (id != null) {
+ serviceOfferingSearch.and("id", serviceOfferingSearch.entity().getId(), SearchCriteria.Op.EQ);
+ }
+
+ if (isSystem != null) {
+ // note that for non-root users, isSystem is always false when
+ // control comes to here
+ serviceOfferingSearch.and("systemUse", serviceOfferingSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
+ }
+
+ if (name != null) {
+ serviceOfferingSearch.and("name", serviceOfferingSearch.entity().getName(), SearchCriteria.Op.EQ);
+ }
+
+ if (vmTypeStr != null) {
+ serviceOfferingSearch.and("svmType", serviceOfferingSearch.entity().getVmType(), SearchCriteria.Op.EQ);
+ }
+ DataCenterJoinVO zone = null;
+ if (zoneId != null) {
+ SearchBuilder<ServiceOfferingDetailsVO> srvOffrZoneDetailSearch = _srvOfferingDetailsDao.createSearchBuilder();
+ srvOffrZoneDetailSearch.and().op("zoneId", srvOffrZoneDetailSearch.entity().getValue(), Op.EQ);
+ srvOffrZoneDetailSearch.or("idNull", srvOffrZoneDetailSearch.entity().getId(), Op.NULL);
+ srvOffrZoneDetailSearch.cp();
+
+ serviceOfferingSearch.join("ZoneDetailSearch", srvOffrZoneDetailSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), srvOffrZoneDetailSearch.entity().getResourceId(),
+ srvOffrZoneDetailSearch.entity().getName(), serviceOfferingSearch.entity().setString(ApiConstants.ZONE_ID));
+ zone = _dcJoinDao.findById(zoneId);
+ }
+
+ if (encryptRoot != null || vmId != null || (zone != null && DataCenter.Type.Edge.equals(zone.getType()))) {
+ SearchBuilder<DiskOfferingVO> diskOfferingSearch = _diskOfferingDao.createSearchBuilder();
+ diskOfferingSearch.and("useLocalStorage", diskOfferingSearch.entity().isUseLocalStorage(), SearchCriteria.Op.EQ);
+ diskOfferingSearch.and("encrypt", diskOfferingSearch.entity().getEncrypt(), SearchCriteria.Op.EQ);
+
+ if (diskOffering != null) {
+ List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
+ if (!storageTags.isEmpty() && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.value()) {
+ for (String tag : storageTags) {
+ diskOfferingSearch.and(tag, diskOfferingSearch.entity().getTags(), Op.EQ);
+ }
+ diskOfferingSearch.done();
+ }
+ }
+
+ serviceOfferingSearch.join("diskOfferingSearch", diskOfferingSearch, JoinBuilder.JoinType.INNER, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getDiskOfferingId(), diskOfferingSearch.entity().getId(),
+ serviceOfferingSearch.entity().setString("Active"), diskOfferingSearch.entity().getState());
+ }
+
+ if (cpuNumber != null) {
+ SearchBuilder<ServiceOfferingDetailsVO> maxComputeDetailsSearch = (SearchBuilder<ServiceOfferingDetailsVO>) serviceOfferingSearch.getJoinSB("maxComputeDetailsSearch");
+ if (maxComputeDetailsSearch == null) {
+ maxComputeDetailsSearch = _srvOfferingDetailsDao.createSearchBuilder();
+ serviceOfferingSearch.join("maxComputeDetailsSearch", maxComputeDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), maxComputeDetailsSearch.entity().getResourceId(),
+ maxComputeDetailsSearch.entity().getName(), serviceOfferingSearch.entity().setString(ApiConstants.MAX_CPU_NUMBER));
+ }
+
+ SearchBuilder<ServiceOfferingDetailsVO> minComputeDetailsSearch = _srvOfferingDetailsDao.createSearchBuilder();
+
+ serviceOfferingSearch.join("minComputeDetailsSearch", minComputeDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), minComputeDetailsSearch.entity().getResourceId(),
+ minComputeDetailsSearch.entity().getName(), serviceOfferingSearch.entity().setString(ApiConstants.MIN_CPU_NUMBER));
+
+ /*
+ (min_cpu IS NULL AND cpu IS NULL AND max_cpu IS NULL)
+ OR (cpu = X)
+ OR (min_cpu <= X AND max_cpu >= X)
+
+ AND (
+ (min_compute_details.value is NULL AND cpu is NULL)
+ OR (min_compute_details.value is NULL AND cpu >= X)
+ OR min_compute_details.value >= X
+ OR (
+ ((min_compute_details.value is NULL AND cpu <= X) OR min_compute_details.value <= X)
+ AND ((max_compute_details.value is NULL AND cpu >= X) OR max_compute_details.value >= X)
+ )
+ )
+ */
+ serviceOfferingSearch.and().op().op("minComputeDetailsSearch", "cpuConstraintMinComputeNull", minComputeDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("cpuConstraintNull", serviceOfferingSearch.entity().getCpu(), Op.NULL).cp();
+
+ serviceOfferingSearch.or().op("minComputeDetailsSearch", "cpuConstraintMinComputeNull", minComputeDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("cpuNumber", serviceOfferingSearch.entity().getCpu(), Op.GTEQ).cp();
+ serviceOfferingSearch.or("cpuNumber", serviceOfferingSearch.entity().getCpu(), Op.GTEQ);
+
+ serviceOfferingSearch.or().op().op();
+ serviceOfferingSearch.op("minComputeDetailsSearch", "cpuConstraintMinComputeNull", minComputeDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("cpuNumber", serviceOfferingSearch.entity().getCpu(), Op.LTEQ).cp();
+ serviceOfferingSearch.or("minComputeDetailsSearch", "cpuNumber", minComputeDetailsSearch.entity().getValue(), Op.LTEQ).cp();
+ serviceOfferingSearch.and().op().op("maxComputeDetailsSearch", "cpuConstraintMaxComputeNull", maxComputeDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("cpuNumber", serviceOfferingSearch.entity().getCpu(), Op.GTEQ).cp();
+ serviceOfferingSearch.or("maxComputeDetailsSearch", "cpuNumber", maxComputeDetailsSearch.entity().getValue(), Op.GTEQ).cp();
+ serviceOfferingSearch.cp().cp();
+ }
+
+ if (memory != null) {
+ SearchBuilder<ServiceOfferingDetailsVO> maxMemoryDetailsSearch = (SearchBuilder<ServiceOfferingDetailsVO>) serviceOfferingSearch.getJoinSB("maxMemoryDetailsSearch");
+ if (maxMemoryDetailsSearch == null) {
+ maxMemoryDetailsSearch = _srvOfferingDetailsDao.createSearchBuilder();
+ serviceOfferingSearch.join("maxMemoryDetailsSearch", maxMemoryDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), maxMemoryDetailsSearch.entity().getResourceId(),
+ maxMemoryDetailsSearch.entity().getName(), serviceOfferingSearch.entity().setString("maxmemory"));
+ }
+
+ SearchBuilder<ServiceOfferingDetailsVO> minMemoryDetailsSearch = _srvOfferingDetailsDao.createSearchBuilder();
+
+ serviceOfferingSearch.join("minMemoryDetailsSearch", minMemoryDetailsSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), minMemoryDetailsSearch.entity().getResourceId(),
+ minMemoryDetailsSearch.entity().getName(), serviceOfferingSearch.entity().setString("minmemory"));
+
+ /*
+ (min_ram_size IS NULL AND ram_size IS NULL AND max_ram_size IS NULL)
+ OR (ram_size = X)
+ OR (min_ram_size <= X AND max_ram_size >= X)
+ */
+
+ serviceOfferingSearch.and().op().op("minMemoryDetailsSearch", "memoryConstraintMinMemoryNull", minMemoryDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("memoryConstraintNull", serviceOfferingSearch.entity().getRamSize(), Op.NULL).cp();
+
+ serviceOfferingSearch.or().op("minMemoryDetailsSearch", "memoryConstraintMinMemoryNull", minMemoryDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("memory", serviceOfferingSearch.entity().getRamSize(), Op.GTEQ).cp();
+ serviceOfferingSearch.or("memory", serviceOfferingSearch.entity().getRamSize(), Op.GTEQ);
+
+ serviceOfferingSearch.or().op().op();
+ serviceOfferingSearch.op("minMemoryDetailsSearch", "memoryConstraintMinMemoryNull", minMemoryDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("memory", serviceOfferingSearch.entity().getRamSize(), Op.LTEQ).cp();
+ serviceOfferingSearch.or("minMemoryDetailsSearch", "memory", minMemoryDetailsSearch.entity().getValue(), Op.LTEQ).cp();
+ serviceOfferingSearch.and().op().op("maxMemoryDetailsSearch", "memoryConstraintMaxMemoryNull", maxMemoryDetailsSearch.entity().getValue(), Op.NULL);
+ serviceOfferingSearch.and("memory", serviceOfferingSearch.entity().getRamSize(), Op.GTEQ).cp();
+ serviceOfferingSearch.or("maxMemoryDetailsSearch", "memory", maxMemoryDetailsSearch.entity().getValue(), Op.GTEQ).cp();
+ serviceOfferingSearch.cp().cp();
+ }
+
+ if (cpuSpeed != null) {
+ serviceOfferingSearch.and().op("speedNull", serviceOfferingSearch.entity().getSpeed(), Op.NULL);
+ serviceOfferingSearch.or("speedGTEQ", serviceOfferingSearch.entity().getSpeed(), Op.GTEQ);
+ serviceOfferingSearch.cp();
+ }
+
+ // Filter offerings that are not associated with caller's domain
+ // Fetch the offering ids from the details table since theres no smart way to filter them in the join ... yet!
+ if (owner.getType() != Account.Type.ADMIN) {
+ SearchBuilder<ServiceOfferingDetailsVO> srvOffrDomainDetailSearch = _srvOfferingDetailsDao.createSearchBuilder();
+ srvOffrDomainDetailSearch.and().op("domainIdIN", srvOffrDomainDetailSearch.entity().getValue(), Op.IN);
+ srvOffrDomainDetailSearch.or("idNull", srvOffrDomainDetailSearch.entity().getValue(), Op.NULL);
+ srvOffrDomainDetailSearch.cp();
+ serviceOfferingSearch.join("domainDetailSearchNormalUser", srvOffrDomainDetailSearch, JoinBuilder.JoinType.LEFT, JoinBuilder.JoinCondition.AND,
+ serviceOfferingSearch.entity().getId(), srvOffrDomainDetailSearch.entity().getResourceId(),
+ srvOffrDomainDetailSearch.entity().getName(), serviceOfferingSearch.entity().setString(ApiConstants.DOMAIN_ID));
+ }
+
+ if (currentVmOffering != null) {
+ List<String> hostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
+ if (!hostTags.isEmpty()) {
+
+ serviceOfferingSearch.and().op("hostTag", serviceOfferingSearch.entity().getHostTag(), Op.NULL);
+ serviceOfferingSearch.or().op();
+
+ for(String tag : hostTags) {
+ serviceOfferingSearch.and(tag, serviceOfferingSearch.entity().getHostTag(), Op.EQ);
+ }
+ serviceOfferingSearch.cp().cp().done();
+ }
+ }
+
+ SearchCriteria<ServiceOfferingVO> sc = serviceOfferingSearch.create();
+ sc.setParameters("activeState", ServiceOffering.State.Active);
+
+ if (vmId != null) {
+ if (!currentVmOffering.isDynamic()) {
+ sc.setParameters("idNEQ", currentVmOffering.getId());
+ }
+
+ if (currentVmOffering.getDiskOfferingStrictness()) {
+ sc.setParameters("diskOfferingId", currentVmOffering.getDiskOfferingId());
+ sc.setParameters("diskOfferingStrictness", true);
+ } else {
+ sc.setParameters("diskOfferingStrictness", false);
+ }
+
+ boolean isRootVolumeUsingLocalStorage = virtualMachineManager.isRootVolumeOnLocalStorage(vmId);
+
+ // 1. Only return offerings with the same storage type than the storage pool where the VM's root volume is allocated
+ sc.setJoinParameters("diskOfferingSearch", "useLocalStorage", isRootVolumeUsingLocalStorage);
+
+ // 2.In case vm is running return only offerings greater than equal to current offering compute and offering's dynamic scalability should match
+ if (vmInstance.getState() == VirtualMachine.State.Running) {
+ Integer vmCpu = currentVmOffering.getCpu();
+ Integer vmMemory = currentVmOffering.getRamSize();
+ Integer vmSpeed = currentVmOffering.getSpeed();
+ if ((vmCpu == null || vmMemory == null || vmSpeed == null) && VirtualMachine.Type.User.equals(vmInstance.getType())) {
+ UserVmVO userVmVO = userVmDao.findById(vmId);
+ userVmDao.loadDetails(userVmVO);
+ Map<String, String> details = userVmVO.getDetails();
+ vmCpu = NumbersUtil.parseInt(details.get(ApiConstants.CPU_NUMBER), 0);
+ if (vmSpeed == null) {
+ vmSpeed = NumbersUtil.parseInt(details.get(ApiConstants.CPU_SPEED), 0);
+ }
+ vmMemory = NumbersUtil.parseInt(details.get(ApiConstants.MEMORY), 0);
+ }
+ if (vmCpu != null && vmCpu > 0) {
+ sc.setParameters("vmCpu", vmCpu);
+ sc.setParameters("vmMaxComputeGTEQ", vmCpu);
+ }
+ if (vmSpeed != null && vmSpeed > 0) {
+ sc.setParameters("speedGTEQ", vmSpeed);
+ }
+ if (vmMemory != null && vmMemory > 0) {
+ sc.setParameters("vmMemory", vmMemory);
+ sc.setParameters("vmMaxMemoryGTEQ", vmMemory);
+ }
+ sc.setParameters("dynamicScalingEnabled", currentVmOffering.isDynamicScalingEnabled());
+ }
+ }
+
+ if ((!accountMgr.isNormalUser(caller.getId()) && !accountMgr.isDomainAdmin(caller.getId())) && caller.getType() != Account.Type.RESOURCE_DOMAIN_ADMIN) {
+ if (domainId != null && accountName == null) {
+ sc.setJoinParameters("domainDetailSearch", "domainId", domainId);
+ }
+ }
+
+ if (keyword != null) {
+ sc.setParameters("keywordName", "%" + keyword + "%");
+ sc.setParameters("keywordDisplayText", "%" + keyword + "%");
}
if (id != null) {
- sc.addAnd("id", SearchCriteria.Op.EQ, id);
+ sc.setParameters("id", id);
}
if (isSystem != null) {
// note that for non-root users, isSystem is always false when
// control comes to here
- sc.addAnd("systemUse", SearchCriteria.Op.EQ, isSystem);
+ sc.setParameters("systemUse", isSystem);
}
if (encryptRoot != null) {
- sc.addAnd("encryptRoot", SearchCriteria.Op.EQ, encryptRoot);
+ sc.setJoinParameters("diskOfferingSearch", "encrypt", encryptRoot);
}
if (name != null) {
- sc.addAnd("name", SearchCriteria.Op.EQ, name);
+ sc.setParameters("name", name);
}
if (vmTypeStr != null) {
- sc.addAnd("vmType", SearchCriteria.Op.EQ, vmTypeStr);
+ sc.setParameters("svmType", vmTypeStr);
}
useStorageType(sc, storageType);
if (zoneId != null) {
- SearchBuilder<ServiceOfferingJoinVO> sb = _srvOfferingJoinDao.createSearchBuilder();
- sb.and("zoneId", sb.entity().getZoneId(), Op.FIND_IN_SET);
- sb.or("zId", sb.entity().getZoneId(), Op.NULL);
- sb.done();
- SearchCriteria<ServiceOfferingJoinVO> zoneSC = sb.create();
- zoneSC.setParameters("zoneId", String.valueOf(zoneId));
- sc.addAnd("zoneId", SearchCriteria.Op.SC, zoneSC);
- DataCenterJoinVO zone = _dcJoinDao.findById(zoneId);
+ sc.setJoinParameters("ZoneDetailSearch", "zoneId", zoneId);
+
if (DataCenter.Type.Edge.equals(zone.getType())) {
- sc.addAnd("useLocalStorage", Op.EQ, true);
+ sc.setJoinParameters("diskOfferingSearch", "useLocalStorage", true);
}
}
if (cpuNumber != null) {
- SearchCriteria<ServiceOfferingJoinVO> cpuConstraintSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
- cpuConstraintSearchCriteria.addAnd("minCpu", Op.LTEQ, cpuNumber);
- cpuConstraintSearchCriteria.addAnd("maxCpu", Op.GTEQ, cpuNumber);
-
- SearchCriteria<ServiceOfferingJoinVO> cpuSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
- cpuSearchCriteria.addOr("minCpu", Op.NULL);
- cpuSearchCriteria.addOr("constraints", Op.SC, cpuConstraintSearchCriteria);
- cpuSearchCriteria.addOr("minCpu", Op.GTEQ, cpuNumber);
-
- sc.addAnd("cpuConstraints", SearchCriteria.Op.SC, cpuSearchCriteria);
+ sc.setParameters("cpuNumber", cpuNumber);
}
if (memory != null) {
- SearchCriteria<ServiceOfferingJoinVO> memoryConstraintSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
- memoryConstraintSearchCriteria.addAnd("minMemory", Op.LTEQ, memory);
- memoryConstraintSearchCriteria.addAnd("maxMemory", Op.GTEQ, memory);
-
- SearchCriteria<ServiceOfferingJoinVO> memSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
- memSearchCriteria.addOr("minMemory", Op.NULL);
- memSearchCriteria.addOr("memconstraints", Op.SC, memoryConstraintSearchCriteria);
- memSearchCriteria.addOr("minMemory", Op.GTEQ, memory);
-
- sc.addAnd("memoryConstraints", SearchCriteria.Op.SC, memSearchCriteria);
+ sc.setParameters("memory", memory);
}
if (cpuSpeed != null) {
- SearchCriteria<ServiceOfferingJoinVO> cpuSpeedSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
- cpuSpeedSearchCriteria.addOr("speed", Op.NULL);
- cpuSpeedSearchCriteria.addOr("speed", Op.GTEQ, cpuSpeed);
- sc.addAnd("cpuspeedconstraints", SearchCriteria.Op.SC, cpuSpeedSearchCriteria);
+ sc.setParameters("speedGTEQ", cpuSpeed);
}
- // Filter offerings that are not associated with caller's domain
- // Fetch the offering ids from the details table since theres no smart way to filter them in the join ... yet!
if (owner.getType() != Account.Type.ADMIN) {
Domain callerDomain = _domainDao.findById(owner.getDomainId());
List<Long> domainIds = findRelatedDomainIds(callerDomain, isRecursive);
- List<Long> ids = _srvOfferingDetailsDao.findOfferingIdsByDomainIds(domainIds);
- SearchBuilder<ServiceOfferingJoinVO> sb = _srvOfferingJoinDao.createSearchBuilder();
- if (ids != null && !ids.isEmpty()) {
- sb.and("id", sb.entity().getId(), Op.IN);
- }
- sb.or("domainId", sb.entity().getDomainId(), Op.NULL);
- sb.done();
-
- SearchCriteria<ServiceOfferingJoinVO> scc = sb.create();
- if (ids != null && !ids.isEmpty()) {
- scc.setParameters("id", ids.toArray());
- }
- sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
+ sc.setJoinParameters("domainDetailSearchNormalUser", "domainIdIN", domainIds.toArray());
}
if (currentVmOffering != null) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentVmOffering.getDiskOfferingId());
- List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
- if (!storageTags.isEmpty() && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.value()) {
- SearchBuilder<ServiceOfferingJoinVO> sb = _srvOfferingJoinDao.createSearchBuilder();
- for(String tag : storageTags) {
- sb.and(tag, sb.entity().getTags(), Op.FIND_IN_SET);
- }
- sb.done();
- SearchCriteria<ServiceOfferingJoinVO> scc = sb.create();
- for(String tag : storageTags) {
- scc.setParameters(tag, tag);
+ if (diskOffering != null) {
+ List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
+ if (!storageTags.isEmpty() && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.value()) {
+ for(String tag : storageTags) {
+ sc.setJoinParameters("diskOfferingSearch", tag, tag);
+ }
}
- sc.addAnd("storageTags", SearchCriteria.Op.SC, scc);
}
List<String> hostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
if (!hostTags.isEmpty()) {
- SearchBuilder<ServiceOfferingJoinVO> hostTagsSearchBuilder = _srvOfferingJoinDao.createSearchBuilder();
- for(String tag : hostTags) {
- hostTagsSearchBuilder.and(tag, hostTagsSearchBuilder.entity().getHostTag(), Op.FIND_IN_SET);
- }
- hostTagsSearchBuilder.done();
-
- SearchCriteria<ServiceOfferingJoinVO> hostTagsSearchCriteria = hostTagsSearchBuilder.create();
for(String tag : hostTags) {
- hostTagsSearchCriteria.setParameters(tag, tag);
+ sc.setParameters(tag, tag);
}
-
- SearchCriteria<ServiceOfferingJoinVO> finalHostTagsSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
- finalHostTagsSearchCriteria.addOr("hostTag", Op.NULL);
- finalHostTagsSearchCriteria.addOr("hostTag", Op.SC, hostTagsSearchCriteria);
-
- sc.addAnd("hostTagsConstraint", SearchCriteria.Op.SC, finalHostTagsSearchCriteria);
}
}
- return _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
+ Pair<List<ServiceOfferingVO>, Integer> uniquePair = _srvOfferingDao.searchAndCount(sc, searchFilter);
+ Integer count = uniquePair.second();
+ List<Long> offeringIds = uniquePair.first().stream().map(ServiceOfferingVO::getId).collect(Collectors.toList());
+ return new Pair<>(offeringIds, count);
}
@Override
diff --git a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
index 44096a799b7..623ba436d0e 100644
--- a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
@@ -541,11 +541,7 @@ public class ViewResponseHelper {
}
public static List<AccountResponse> createAccountResponse(ResponseView view, EnumSet<DomainDetails> details, AccountJoinVO... accounts) {
- List<AccountResponse> respList = new ArrayList<AccountResponse>();
- for (AccountJoinVO vt : accounts){
- respList.add(ApiDBUtils.newAccountResponse(view, details, vt));
- }
- return respList;
+ return ApiDBUtils.newAccountResponses(view, details, accounts);
}
public static List<AsyncJobResponse> createAsyncJobResponse(AsyncJobJoinVO... jobs) {
diff --git a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDao.java
index 42842f568b4..16bda5b4aa9 100644
--- a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDao.java
+++ b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDao.java
@@ -17,6 +17,7 @@
package com.cloud.api.query.dao;
import java.util.EnumSet;
+import java.util.List;
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
@@ -35,4 +36,5 @@ public interface AccountJoinDao extends GenericDao<AccountJoinVO, Long> {
void setResourceLimits(AccountJoinVO account, boolean accountIsAdmin, ResourceLimitAndCountResponse response);
+ List<AccountJoinVO> searchByIds(Long... ids);
}
diff --git a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
index 790758c627f..2daa411e4fb 100644
--- a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
@@ -16,11 +16,13 @@
// under the License.
package com.cloud.api.query.dao;
+import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.inject.Inject;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@@ -46,12 +48,19 @@ import com.cloud.utils.db.SearchCriteria;
public class AccountJoinDaoImpl extends GenericDaoBase<AccountJoinVO, Long> implements AccountJoinDao {
public static final Logger s_logger = Logger.getLogger(AccountJoinDaoImpl.class);
+ @Inject
+ private ConfigurationDao configDao;
private final SearchBuilder<AccountJoinVO> acctIdSearch;
+ private final SearchBuilder<AccountJoinVO> domainSearch;
@Inject
AccountManager _acctMgr;
protected AccountJoinDaoImpl() {
+ domainSearch = createSearchBuilder();
+ domainSearch.and("idIN", domainSearch.entity().getId(), SearchCriteria.Op.IN);
+ domainSearch.done();
+
acctIdSearch = createSearchBuilder();
acctIdSearch.and("id", acctIdSearch.entity().getId(), SearchCriteria.Op.EQ);
acctIdSearch.done();
@@ -232,6 +241,50 @@ public class AccountJoinDaoImpl extends GenericDaoBase<AccountJoinVO, Long> impl
response.setSecondaryStorageAvailable(secondaryStorageAvail);
}
+ @Override
+ public List<AccountJoinVO> searchByIds(Long... accountIds) {
+ // set detail batch query size
+ int DETAILS_BATCH_SIZE = 2000;
+ String batchCfg = configDao.getValue("detail.batch.query.size");
+ if (batchCfg != null) {
+ DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
+ }
+
+ List<AccountJoinVO> uvList = new ArrayList<>();
+ // query details by batches
+ int curr_index = 0;
+ if (accountIds.length > DETAILS_BATCH_SIZE) {
+ while ((curr_index + DETAILS_BATCH_SIZE) <= accountIds.length) {
+ Long[] ids = new Long[DETAILS_BATCH_SIZE];
+ for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
+ ids[k] = accountIds[j];
+ }
+ SearchCriteria<AccountJoinVO> sc = domainSearch.create();
+ sc.setParameters("idIN", ids);
+ List<AccountJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
+ if (accounts != null) {
+ uvList.addAll(accounts);
+ }
+ curr_index += DETAILS_BATCH_SIZE;
+ }
+ }
+ if (curr_index < accountIds.length) {
+ int batch_size = (accountIds.length - curr_index);
+ // set the ids value
+ Long[] ids = new Long[batch_size];
+ for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+ ids[k] = accountIds[j];
+ }
+ SearchCriteria<AccountJoinVO> sc = domainSearch.create();
+ sc.setParameters("idIN", ids);
+ List<AccountJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
+ if (accounts != null) {
+ uvList.addAll(accounts);
+ }
+ }
+ return uvList;
+ }
+
@Override
public AccountJoinVO newAccountView(Account acct) {
SearchCriteria<AccountJoinVO> sc = acctIdSearch.create();
diff --git a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDao.java
index 3d612c63d38..3b38a562d58 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDao.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDao.java
@@ -33,4 +33,6 @@ public interface DiskOfferingJoinDao extends GenericDao<DiskOfferingJoinVO, Long
DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO dof);
DiskOfferingJoinVO newDiskOfferingView(DiskOffering dof);
+
+ List<DiskOfferingJoinVO> searchByIds(Long... idArray);
}
diff --git a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
index 9592986151f..5341b3b56d7 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
@@ -16,6 +16,7 @@
// under the License.
package com.cloud.api.query.dao;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -26,6 +27,7 @@ import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@@ -51,9 +53,12 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO,
@Inject
private AnnotationDao annotationDao;
@Inject
+ private ConfigurationDao configDao;
+ @Inject
private AccountManager accountManager;
private final SearchBuilder<DiskOfferingJoinVO> dofIdSearch;
+ private SearchBuilder<DiskOfferingJoinVO> diskOfferingSearch;
private final Attribute _typeAttr;
protected DiskOfferingJoinDaoImpl() {
@@ -62,6 +67,11 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO,
dofIdSearch.and("id", dofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
dofIdSearch.done();
+ diskOfferingSearch = createSearchBuilder();
+ diskOfferingSearch.and("idIN", diskOfferingSearch.entity().getId(), SearchCriteria.Op.IN);
+ diskOfferingSearch.done();
+
+
_typeAttr = _allAttributes.get("type");
_count = "select count(distinct id) from disk_offering_view WHERE ";
@@ -154,4 +164,48 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO,
assert offerings != null && offerings.size() == 1 : "No disk offering found for offering id " + offering.getId();
return offerings.get(0);
}
+
+ @Override
+ public List<DiskOfferingJoinVO> searchByIds(Long... offeringIds) {
+ // set detail batch query size
+ int DETAILS_BATCH_SIZE = 2000;
+ String batchCfg = configDao.getValue("detail.batch.query.size");
+ if (batchCfg != null) {
+ DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
+ }
+
+ List<DiskOfferingJoinVO> uvList = new ArrayList<>();
+ // query details by batches
+ int curr_index = 0;
+ if (offeringIds.length > DETAILS_BATCH_SIZE) {
+ while ((curr_index + DETAILS_BATCH_SIZE) <= offeringIds.length) {
+ Long[] ids = new Long[DETAILS_BATCH_SIZE];
+ for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
+ ids[k] = offeringIds[j];
+ }
+ SearchCriteria<DiskOfferingJoinVO> sc = diskOfferingSearch.create();
+ sc.setParameters("idIN", ids);
+ List<DiskOfferingJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
+ if (accounts != null) {
+ uvList.addAll(accounts);
+ }
+ curr_index += DETAILS_BATCH_SIZE;
+ }
+ }
+ if (curr_index < offeringIds.length) {
+ int batch_size = (offeringIds.length - curr_index);
+ // set the ids value
+ Long[] ids = new Long[batch_size];
+ for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+ ids[k] = offeringIds[j];
+ }
+ SearchCriteria<DiskOfferingJoinVO> sc = diskOfferingSearch.create();
+ sc.setParameters("idIN", ids);
+ List<DiskOfferingJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
+ if (accounts != null) {
+ uvList.addAll(accounts);
+ }
+ }
+ return uvList;
+ }
}
diff --git a/server/src/main/java/com/cloud/api/query/dao/DomainJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDao.java
index 94efc28d2d4..c7960fd1110 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DomainJoinDao.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDao.java
@@ -17,6 +17,7 @@
package com.cloud.api.query.dao;
import java.util.EnumSet;
+import java.util.List;
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
@@ -35,4 +36,5 @@ public interface DomainJoinDao extends GenericDao<DomainJoinVO, Long> {
void setResourceLimits(DomainJoinVO domain, boolean isRootDomain, ResourceLimitAndCountResponse response);
+ List<DomainJoinVO> searchByIds(Long... domainIds);
}
diff --git a/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
index 56f5417da3f..24200fa84f9 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
@@ -16,6 +16,7 @@
// under the License.
package com.cloud.api.query.dao;
+import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
@@ -29,6 +30,7 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ResourceLimitAndCountResponse;
import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@@ -47,10 +49,13 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
public static final Logger s_logger = Logger.getLogger(DomainJoinDaoImpl.class);
private SearchBuilder<DomainJoinVO> domainIdSearch;
+ private SearchBuilder<DomainJoinVO> domainSearch;
@Inject
private AnnotationDao annotationDao;
@Inject
+ private ConfigurationDao configDao;
+ @Inject
private AccountManager accountManager;
protected DomainJoinDaoImpl() {
@@ -59,6 +64,10 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
domainIdSearch.and("id", domainIdSearch.entity().getId(), SearchCriteria.Op.EQ);
domainIdSearch.done();
+ domainSearch = createSearchBuilder();
+ domainSearch.and("idIN", domainSearch.entity().getId(), SearchCriteria.Op.IN);
+ domainSearch.done();
+
this._count = "select count(distinct id) from domain_view WHERE ";
}
@@ -207,6 +216,50 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
response.setSecondaryStorageAvailable(secondaryStorageAvail);
}
+ @Override
+ public List<DomainJoinVO> searchByIds(Long... domainIds) {
+ // set detail batch query size
+ int DETAILS_BATCH_SIZE = 2000;
+ String batchCfg = configDao.getValue("detail.batch.query.size");
+ if (batchCfg != null) {
+ DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
+ }
+
+ List<DomainJoinVO> uvList = new ArrayList<>();
+ // query details by batches
+ int curr_index = 0;
+ if (domainIds.length > DETAILS_BATCH_SIZE) {
+ while ((curr_index + DETAILS_BATCH_SIZE) <= domainIds.length) {
+ Long[] ids = new Long[DETAILS_BATCH_SIZE];
+ for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
+ ids[k] = domainIds[j];
+ }
+ SearchCriteria<DomainJoinVO> sc = domainSearch.create();
+ sc.setParameters("idIN", ids);
+ List<DomainJoinVO> domains = searchIncludingRemoved(sc, null, null, false);
+ if (domains != null) {
+ uvList.addAll(domains);
+ }
+ curr_index += DETAILS_BATCH_SIZE;
+ }
+ }
+ if (curr_index < domainIds.length) {
+ int batch_size = (domainIds.length - curr_index);
+ // set the ids value
+ Long[] ids = new Long[batch_size];
+ for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+ ids[k] = domainIds[j];
+ }
+ SearchCriteria<DomainJoinVO> sc = domainSearch.create();
+ sc.setParameters("idIN", ids);
+ List<DomainJoinVO> domains = searchIncludingRemoved(sc, null, null, false);
+ if (domains != null) {
+ uvList.addAll(domains);
+ }
+ }
+ return uvList;
+ }
+
@Override
public DomainJoinVO newDomainView(Domain domain) {
SearchCriteria<DomainJoinVO> sc = domainIdSearch.create();
diff --git a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
index 973e4017529..d28b9fc7e88 100644
--- a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
+++ b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
@@ -34,4 +34,5 @@ public interface ServiceOfferingJoinDao extends GenericDao<ServiceOfferingJoinVO
ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering);
Map<Long, List<String>> listDomainsOfServiceOfferingsUsedByDomainPath(String domainPath);
+ List<ServiceOfferingJoinVO> searchByIds(Long... id);
}
diff --git a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
index 4a81cc8bfee..92175568cd9 100644
--- a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
@@ -21,6 +21,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -34,6 +35,7 @@ import com.cloud.storage.DiskOfferingVO;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@@ -56,10 +58,14 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
@Inject
private AnnotationDao annotationDao;
@Inject
+ private ConfigurationDao configDao;
+ @Inject
private AccountManager accountManager;
private SearchBuilder<ServiceOfferingJoinVO> sofIdSearch;
+ private SearchBuilder<ServiceOfferingJoinVO> srvOfferingSearch;
+
/**
* Constant used to convert GB into Bytes (or the other way around).
* GB * MB * KB = Bytes //
@@ -85,6 +91,10 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
sofIdSearch.and("id", sofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
sofIdSearch.done();
+ srvOfferingSearch = createSearchBuilder();
+ srvOfferingSearch.and("idIN", srvOfferingSearch.entity().getId(), SearchCriteria.Op.IN);
+ srvOfferingSearch.done();
+
this._count = "select count(distinct service_offering_view.id) from service_offering_view WHERE ";
}
@@ -184,7 +194,6 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
return offerings.get(0);
}
-
@Override
public Map<Long, List<String>> listDomainsOfServiceOfferingsUsedByDomainPath(String domainPath) {
s_logger.debug(String.format("Retrieving the domains of the service offerings used by domain with path [%s].", domainPath));
@@ -217,4 +226,48 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
return new HashMap<>();
}
}
+
+ @Override
+ public List<ServiceOfferingJoinVO> searchByIds(Long... offeringIds) {
+ // set detail batch query size
+ int DETAILS_BATCH_SIZE = 2000;
+ String batchCfg = configDao.getValue("detail.batch.query.size");
+ if (batchCfg != null) {
+ DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
+ }
+
+ List<ServiceOfferingJoinVO> uvList = new ArrayList<>();
+ // query details by batches
+ int curr_index = 0;
+ if (offeringIds.length > DETAILS_BATCH_SIZE) {
+ while ((curr_index + DETAILS_BATCH_SIZE) <= offeringIds.length) {
+ Long[] ids = new Long[DETAILS_BATCH_SIZE];
+ for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
+ ids[k] = offeringIds[j];
+ }
+ SearchCriteria<ServiceOfferingJoinVO> sc = srvOfferingSearch.create();
+ sc.setParameters("idIN", ids);
+ List<ServiceOfferingJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
+ if (accounts != null) {
+ uvList.addAll(accounts);
+ }
+ curr_index += DETAILS_BATCH_SIZE;
+ }
+ }
+ if (curr_index < offeringIds.length) {
+ int batch_size = (offeringIds.length - curr_index);
+ // set the ids value
+ Long[] ids = new Long[batch_size];
+ for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+ ids[k] = offeringIds[j];
+ }
+ SearchCriteria<ServiceOfferingJoinVO> sc = srvOfferingSearch.create();
+ sc.setParameters("idIN", ids);
+ List<ServiceOfferingJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
+ if (accounts != null) {
+ uvList.addAll(accounts);
+ }
+ }
+ return uvList;
+ }
}
diff --git a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java
index 9028f3418b3..26ee3f01789 100644
--- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java
+++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java
@@ -19,9 +19,6 @@ package com.cloud.api.query.dao;
import java.util.List;
import com.cloud.storage.ScopeType;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.Filter;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import com.cloud.api.query.vo.StoragePoolJoinVO;
@@ -43,8 +40,6 @@ public interface StoragePoolJoinDao extends GenericDao<StoragePoolJoinVO, Long>
List<StoragePoolJoinVO> searchByIds(Long... spIds);
- Pair<List<StoragePoolJoinVO>, Integer> searchAndCount(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword, Filter searchFilter);
-
List<StoragePoolVO> findStoragePoolByScopeAndRuleTags(Long datacenterId, Long podId, Long clusterId, ScopeType scopeType, List<String> tags);
}
diff --git a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
index e75e86108c7..f3b832d1042 100644
--- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
@@ -23,13 +23,10 @@ import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage;
import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.StorageStats;
import com.cloud.storage.VolumeApiServiceImpl;
import com.cloud.user.AccountManager;
-import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
-import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@@ -311,77 +308,6 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase<StoragePoolJoinVO, Lo
return uvList;
}
- @Override
- public Pair<List<StoragePoolJoinVO>, Integer> searchAndCount(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword, Filter searchFilter) {
- SearchCriteria<StoragePoolJoinVO> sc = createStoragePoolSearchCriteria(storagePoolId, storagePoolName, zoneId, path, podId, clusterId, address, scopeType, status, keyword);
- return searchAndCount(sc, searchFilter);
- }
-
- private SearchCriteria<StoragePoolJoinVO> createStoragePoolSearchCriteria(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword) {
- SearchBuilder<StoragePoolJoinVO> sb = createSearchBuilder();
- sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct
- // ids
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
- sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ);
- sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
- sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
- sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
- sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ);
- sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ);
- sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
- sb.and("parent", sb.entity().getParent(), SearchCriteria.Op.EQ);
-
- SearchCriteria<StoragePoolJoinVO> sc = sb.create();
-
- if (keyword != null) {
- SearchCriteria<StoragePoolJoinVO> ssc = createSearchCriteria();
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
- }
-
- if (storagePoolId != null) {
- sc.setParameters("id", storagePoolId);
- }
-
- if (storagePoolName != null) {
- sc.setParameters("name", storagePoolName);
- }
-
- if (path != null) {
- sc.setParameters("path", path);
- }
- if (zoneId != null) {
- sc.setParameters("dataCenterId", zoneId);
- }
- if (podId != null) {
- SearchCriteria<StoragePoolJoinVO> ssc = createSearchCriteria();
- ssc.addOr("podId", SearchCriteria.Op.EQ, podId);
- ssc.addOr("podId", SearchCriteria.Op.NULL);
-
- sc.addAnd("podId", SearchCriteria.Op.SC, ssc);
- }
- if (address != null) {
- sc.setParameters("hostAddress", address);
- }
- if (clusterId != null) {
- SearchCriteria<StoragePoolJoinVO> ssc = createSearchCriteria();
- ssc.addOr("clusterId", SearchCriteria.Op.EQ, clusterId);
- ssc.addOr("clusterId", SearchCriteria.Op.NULL);
-
- sc.addAnd("clusterId", SearchCriteria.Op.SC, ssc);
- }
- if (scopeType != null) {
- sc.setParameters("scope", scopeType.toString());
- }
- if (status != null) {
- sc.setParameters("status", status.toString());
- }
- sc.setParameters("parent", 0);
- return sc;
- }
@Override
public List<StoragePoolVO> findStoragePoolByScopeAndRuleTags(Long datacenterId, Long podId, Long clusterId, ScopeType scopeType, List<String> tags) {
SearchCriteria<StoragePoolJoinVO> sc = findByDatacenterAndScopeSb.create();
diff --git a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
index 501d413f117..5a0c19955bd 100644
--- a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
@@ -198,11 +198,15 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
List<ImageStoreVO> storesInZone = dataStoreDao.listStoresByZoneId(template.getDataCenterId());
Long[] storeIds = storesInZone.stream().map(ImageStoreVO::getId).toArray(Long[]::new);
List<TemplateDataStoreVO> templatesInStore = _templateStoreDao.listByTemplateNotBypassed(template.getId(), storeIds);
+
+ List<Long> dataStoreIdList = templatesInStore.stream().map(TemplateDataStoreVO::getDataStoreId).collect(Collectors.toList());
+ Map<Long, ImageStoreVO> imageStoreMap = dataStoreDao.listByIds(dataStoreIdList).stream().collect(Collectors.toMap(ImageStoreVO::getId, imageStore -> imageStore));
+
List<Map<String, String>> downloadProgressDetails = new ArrayList<>();
HashMap<String, String> downloadDetailInImageStores = null;
for (TemplateDataStoreVO templateInStore : templatesInStore) {
downloadDetailInImageStores = new HashMap<>();
- ImageStoreVO imageStore = dataStoreDao.findById(templateInStore.getDataStoreId());
+ ImageStoreVO imageStore = imageStoreMap.get(templateInStore.getDataStoreId());
if (imageStore != null) {
downloadDetailInImageStores.put("datastore", imageStore.getName());
if (view.equals(ResponseView.Full)) {
@@ -219,9 +223,12 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
List<Long> poolIds = poolsInZone.stream().map(StoragePoolVO::getId).collect(Collectors.toList());
List<VMTemplateStoragePoolVO> templatesInPool = templatePoolDao.listByTemplateId(template.getId(), poolIds);
+ dataStoreIdList = templatesInStore.stream().map(TemplateDataStoreVO::getDataStoreId).collect(Collectors.toList());
+ Map<Long, StoragePoolVO> storagePoolMap = primaryDataStoreDao.listByIds(dataStoreIdList).stream().collect(Collectors.toMap(StoragePoolVO::getId, store -> store));
+
for (VMTemplateStoragePoolVO templateInPool : templatesInPool) {
downloadDetailInImageStores = new HashMap<>();
- StoragePoolVO storagePool = primaryDataStoreDao.findById(templateInPool.getDataStoreId());
+ StoragePoolVO storagePool = storagePoolMap.get(templateInPool.getDataStoreId());
if (storagePool != null) {
downloadDetailInImageStores.put("datastore", storagePool.getName());
if (view.equals(ResponseView.Full)) {
diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
index 9fad027d6c8..3dbab7d5b68 100644
--- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -7497,7 +7497,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
networkRate = offering.getRateMbps();
} else {
// for domain router service offering, get network rate from
- if (offering.getSystemVmType() != null && offering.getSystemVmType().equalsIgnoreCase(VirtualMachine.Type.DomainRouter.toString())) {
+ if (offering.getVmType() != null && offering.getVmType().equalsIgnoreCase(VirtualMachine.Type.DomainRouter.toString())) {
networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(dataCenterId);
} else {
networkRate = Integer.parseInt(_configDao.getValue(Config.VmNetworkThrottlingRate.key()));
diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
index 18f98e6f99f..ca1967a07e1 100644
--- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
@@ -4286,9 +4286,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
}
final String virtualMachineDomainRouterType = VirtualMachine.Type.DomainRouter.toString();
- if (!virtualMachineDomainRouterType.equalsIgnoreCase(serviceOffering.getSystemVmType())) {
+ if (!virtualMachineDomainRouterType.equalsIgnoreCase(serviceOffering.getVmType())) {
throw new InvalidParameterValueException(String.format("The specified service offering [%s] is of type [%s]. Virtual routers can only be created with service offering "
- + "of type [%s].", serviceOffering, serviceOffering.getSystemVmType(), virtualMachineDomainRouterType.toLowerCase()));
+ + "of type [%s].", serviceOffering, serviceOffering.getVmType(), virtualMachineDomainRouterType.toLowerCase()));
}
}
diff --git a/server/src/main/java/org/apache/cloudstack/acl/RoleManagerImpl.java b/server/src/main/java/org/apache/cloudstack/acl/RoleManagerImpl.java
index ff97d7ecf6f..eeaff613913 100644
--- a/server/src/main/java/org/apache/cloudstack/acl/RoleManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/acl/RoleManagerImpl.java
@@ -94,7 +94,7 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
}
@Override
- public Role findRole(Long id, boolean removePrivateRoles) {
+ public Role findRole(Long id, boolean ignorePrivateRoles) {
if (id == null || id < 1L) {
logger.trace(String.format("Role ID is invalid [%s]", id));
return null;
@@ -104,13 +104,36 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
logger.trace(String.format("Role not found [id=%s]", id));
return null;
}
- if (!isCallerRootAdmin() && (RoleType.Admin == role.getRoleType() || (!role.isPublicRole() && removePrivateRoles))) {
+ if (!isCallerRootAdmin() && (RoleType.Admin == role.getRoleType() || (!role.isPublicRole() && ignorePrivateRoles))) {
logger.debug(String.format("Role [id=%s, name=%s] is either of 'Admin' type or is private and is only visible to 'Root admins'.", id, role.getName()));
return null;
}
return role;
}
+ @Override
+ public List<Role> findRoles(List<Long> ids, boolean ignorePrivateRoles) {
+ List<Role> result = new ArrayList<>();
+ if (CollectionUtils.isEmpty(ids)) {
+ logger.trace(String.format("Role IDs are invalid [%s]", ids));
+ return result;
+ }
+
+ List<RoleVO> roles = roleDao.searchByIds(ids.toArray(new Long[0]));
+ if (CollectionUtils.isEmpty(roles)) {
+ logger.trace(String.format("Roles not found [ids=%s]", ids));
+ return result;
+ }
+ for (Role role : roles) {
+ if (!isCallerRootAdmin() && (RoleType.Admin == role.getRoleType() || (!role.isPublicRole() && ignorePrivateRoles))) {
+ logger.debug(String.format("Role [id=%s, name=%s] is either of 'Admin' type or is private and is only visible to 'Root admins'.", role.getId(), role.getName()));
+ continue;
+ }
+ result.add(role);
+ }
+ return result;
+ }
+
@Override
public Role findRole(Long id) {
return findRole(id, false);
diff --git a/server/src/test/java/com/cloud/api/query/QueryManagerImplTest.java b/server/src/test/java/com/cloud/api/query/QueryManagerImplTest.java
index 4af84cfa814..be8978e799b 100644
--- a/server/src/test/java/com/cloud/api/query/QueryManagerImplTest.java
+++ b/server/src/test/java/com/cloud/api/query/QueryManagerImplTest.java
@@ -20,6 +20,8 @@ package com.cloud.api.query;
import com.cloud.api.query.dao.TemplateJoinDao;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.TemplateJoinVO;
+import com.cloud.event.EventVO;
+import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.EventJoinDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
@@ -92,6 +94,9 @@ public class QueryManagerImplTest {
@Mock
AccountManager accountManager;
+ @Mock
+ EventDao eventDao;
+
@Mock
EventJoinDao eventJoinDao;
@@ -128,12 +133,12 @@ public class QueryManagerImplTest {
UUID.randomUUID().toString(), User.Source.UNKNOWN);
CallContext.register(user, account);
Mockito.when(accountManager.isRootAdmin(account.getId())).thenReturn(false);
- final SearchBuilder<EventJoinVO> searchBuilder = Mockito.mock(SearchBuilder.class);
- final SearchCriteria<EventJoinVO> searchCriteria = Mockito.mock(SearchCriteria.class);
- final EventJoinVO eventJoinVO = Mockito.mock(EventJoinVO.class);
- when(searchBuilder.entity()).thenReturn(eventJoinVO);
- when(searchBuilder.create()).thenReturn(searchCriteria);
- Mockito.when(eventJoinDao.createSearchBuilder()).thenReturn(searchBuilder);
+ final SearchBuilder<EventVO> eventSearchBuilder = Mockito.mock(SearchBuilder.class);
+ final SearchCriteria<EventVO> eventSearchCriteria = Mockito.mock(SearchCriteria.class);
+ final EventVO eventVO = Mockito.mock(EventVO.class);
+ when(eventSearchBuilder.entity()).thenReturn(eventVO);
+ when(eventSearchBuilder.create()).thenReturn(eventSearchCriteria);
+ Mockito.when(eventDao.createSearchBuilder()).thenReturn(eventSearchBuilder);
}
private ListEventsCmd setupMockListEventsCmd() {
@@ -149,19 +154,26 @@ public class QueryManagerImplTest {
String uuid = UUID.randomUUID().toString();
Mockito.when(cmd.getResourceId()).thenReturn(uuid);
Mockito.when(cmd.getResourceType()).thenReturn(ApiCommandResourceType.Network.toString());
- List<EventJoinVO> events = new ArrayList<>();
- events.add(Mockito.mock(EventJoinVO.class));
- events.add(Mockito.mock(EventJoinVO.class));
- events.add(Mockito.mock(EventJoinVO.class));
- Pair<List<EventJoinVO>, Integer> pair = new Pair<>(events, events.size());
+ List<EventVO> events = new ArrayList<>();
+ events.add(Mockito.mock(EventVO.class));
+ events.add(Mockito.mock(EventVO.class));
+ events.add(Mockito.mock(EventVO.class));
+ Pair<List<EventVO>, Integer> pair = new Pair<>(events, events.size());
+
+ List<EventJoinVO> eventJoins = new ArrayList<>();
+ eventJoins.add(Mockito.mock(EventJoinVO.class));
+ eventJoins.add(Mockito.mock(EventJoinVO.class));
+ eventJoins.add(Mockito.mock(EventJoinVO.class));
+
NetworkVO network = Mockito.mock(NetworkVO.class);
Mockito.when(network.getId()).thenReturn(1L);
Mockito.when(network.getAccountId()).thenReturn(account.getId());
Mockito.when(entityManager.findByUuidIncludingRemoved(Network.class, uuid)).thenReturn(network);
Mockito.doNothing().when(accountManager).checkAccess(account, SecurityChecker.AccessType.ListEntry, true, network);
- Mockito.when(eventJoinDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class))).thenReturn(pair);
+ Mockito.when(eventDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class))).thenReturn(pair);
+ Mockito.when(eventJoinDao.searchByIds(Mockito.any())).thenReturn(eventJoins);
List<EventResponse> respList = new ArrayList<EventResponse>();
- for (EventJoinVO vt : events) {
+ for (EventJoinVO vt : eventJoins) {
respList.add(eventJoinDao.newEventResponse(vt));
}
try (MockedStatic<ViewResponseHelper> ignored = Mockito.mockStatic(ViewResponseHelper.class)) {
diff --git a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
index c993f7b7095..c1e95874d73 100644
--- a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
+++ b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
@@ -789,10 +789,10 @@ public class NetworkServiceImplTest {
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenSystemVmTypeIsNotDomainRouter() {
doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findById(anyLong());
doReturn(ServiceOffering.State.Active).when(serviceOfferingVoMock).getState();
- doReturn(VirtualMachine.Type.ElasticLoadBalancerVm.toString()).when(serviceOfferingVoMock).getSystemVmType();
+ doReturn(VirtualMachine.Type.ElasticLoadBalancerVm.toString()).when(serviceOfferingVoMock).getVmType();
String expectedMessage = String.format("The specified service offering [%s] is of type [%s]. Virtual routers can only be created with service offering of type [%s].",
- serviceOfferingVoMock, serviceOfferingVoMock.getSystemVmType(), VirtualMachine.Type.DomainRouter.toString().toLowerCase());
+ serviceOfferingVoMock, serviceOfferingVoMock.getVmType(), VirtualMachine.Type.DomainRouter.toString().toLowerCase());
InvalidParameterValueException assertThrows = Assert.assertThrows(expectedException, () -> {
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
});
diff --git a/server/src/test/java/com/cloud/user/MockUsageEventDao.java b/server/src/test/java/com/cloud/user/MockUsageEventDao.java
index 4639c509249..52e1b1a02b4 100644
--- a/server/src/test/java/com/cloud/user/MockUsageEventDao.java
+++ b/server/src/test/java/com/cloud/user/MockUsageEventDao.java
@@ -297,6 +297,11 @@ public class MockUsageEventDao implements UsageEventDao{
return null;
}
+ @Override
+ public List<UsageEventVO> findByUuids(String... uuids) {
+ return null;
+ }
+
@Override
public List<UsageEventVO> listLatestEvents(Date endDate) {
return null;