Use join instead of views (#8321)

This commit is contained in:
Vishesh 2024-03-18 22:38:19 +05:30 committed by GitHub
parent ffd59720dd
commit 0043540fa3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 1601 additions and 584 deletions

View File

@ -102,7 +102,7 @@ public interface ServiceOffering extends InfrastructureEntity, InternalIdentity,
boolean getDefaultUse(); boolean getDefaultUse();
String getSystemVmType(); String getVmType();
String getDeploymentPlanner(); String getDeploymentPlanner();

View File

@ -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'. * 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. * 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); Role findRole(Long id);

View File

@ -25,4 +25,18 @@ import java.io.Serializable;
public interface InternalIdentity extends Serializable { public interface InternalIdentity extends Serializable {
long getId(); 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;
}
} }

View File

@ -194,7 +194,7 @@ public class ServiceOfferingVO implements ServiceOffering {
limitCpuUse = offering.getLimitCpuUse(); limitCpuUse = offering.getLimitCpuUse();
volatileVm = offering.isVolatileVm(); volatileVm = offering.isVolatileVm();
hostTag = offering.getHostTag(); hostTag = offering.getHostTag();
vmType = offering.getSystemVmType(); vmType = offering.getVmType();
systemUse = offering.isSystemUse(); systemUse = offering.isSystemUse();
dynamicScalingEnabled = offering.isDynamicScalingEnabled(); dynamicScalingEnabled = offering.isDynamicScalingEnabled();
diskOfferingStrictness = offering.diskOfferingStrictness; diskOfferingStrictness = offering.diskOfferingStrictness;
@ -278,7 +278,7 @@ public class ServiceOfferingVO implements ServiceOffering {
} }
@Override @Override
public String getSystemVmType() { public String getVmType() {
return vmType; return vmType;
} }

View File

@ -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> findAllByRoleType(RoleType type, Long offset, Long limit, boolean showPrivateRole);
Pair<List<RoleVO>, Integer> listAllRoles(Long startIndex, Long limit, boolean showPrivateRole); Pair<List<RoleVO>, Integer> listAllRoles(Long startIndex, Long limit, boolean showPrivateRole);
List<RoleVO> searchByIds(Long... ids);
} }

View File

@ -28,10 +28,13 @@ import org.apache.cloudstack.acl.RoleVO;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List; import java.util.List;
@Component @Component
public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao { public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao {
private final SearchBuilder<RoleVO> RoleByIdsSearch;
private final SearchBuilder<RoleVO> RoleByNameSearch; private final SearchBuilder<RoleVO> RoleByNameSearch;
private final SearchBuilder<RoleVO> RoleByTypeSearch; private final SearchBuilder<RoleVO> RoleByTypeSearch;
private final SearchBuilder<RoleVO> RoleByNameAndTypeSearch; private final SearchBuilder<RoleVO> RoleByNameAndTypeSearch;
@ -40,6 +43,10 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
public RoleDaoImpl() { public RoleDaoImpl() {
super(); super();
RoleByIdsSearch = createSearchBuilder();
RoleByIdsSearch.and("idIN", RoleByIdsSearch.entity().getId(), SearchCriteria.Op.IN);
RoleByIdsSearch.done();
RoleByNameSearch = createSearchBuilder(); RoleByNameSearch = createSearchBuilder();
RoleByNameSearch.and("roleName", RoleByNameSearch.entity().getName(), SearchCriteria.Op.LIKE); RoleByNameSearch.and("roleName", RoleByNameSearch.entity().getName(), SearchCriteria.Op.LIKE);
RoleByNameSearch.and("isPublicRole", RoleByNameSearch.entity().isPublicRole(), SearchCriteria.Op.EQ); 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)); 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) { public void filterPrivateRolesIfNeeded(SearchCriteria<RoleVO> sc, boolean showPrivateRole) {
if (!showPrivateRole) { if (!showPrivateRole) {
sc.setParameters("isPublicRole", true); sc.setParameters("isPublicRole", true);

View File

@ -65,6 +65,10 @@ public class DiskOfferingDetailVO implements ResourceDetail {
return name; return name;
} }
public void setName(String name) {
this.name = name;
}
@Override @Override
public String getValue() { public String getValue() {
return value; return value;

View File

@ -51,4 +51,6 @@ public interface ImageStoreDao extends GenericDao<ImageStoreVO, Long> {
ImageStoreVO findOneByZoneAndProtocol(long zoneId, String protocol); ImageStoreVO findOneByZoneAndProtocol(long zoneId, String protocol);
List<ImageStoreVO> listImageStoresByZoneIds(Long... zoneIds); List<ImageStoreVO> listImageStoresByZoneIds(Long... zoneIds);
List<ImageStoreVO> listByIds(List<Long> ids);
} }

View File

@ -18,12 +18,14 @@
*/ */
package org.apache.cloudstack.storage.datastore.db; package org.apache.cloudstack.storage.datastore.db;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.utils.db.Filter; import com.cloud.utils.db.Filter;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; 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> zoneProtocolSearch;
private SearchBuilder<ImageStoreVO> zonesInSearch; private SearchBuilder<ImageStoreVO> zonesInSearch;
private SearchBuilder<ImageStoreVO> IdsSearch;
public ImageStoreDaoImpl() { public ImageStoreDaoImpl() {
super(); super();
@ -62,6 +65,9 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
zonesInSearch.and("zonesIn", zonesInSearch.entity().getDcId(), SearchCriteria.Op.IN); zonesInSearch.and("zonesIn", zonesInSearch.entity().getDcId(), SearchCriteria.Op.IN);
zonesInSearch.done(); zonesInSearch.done();
IdsSearch = createSearchBuilder();
IdsSearch.and("ids", IdsSearch.entity().getId(), SearchCriteria.Op.IN);
IdsSearch.done();
} }
@Override @Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { 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); sc.setParametersIfNotNull("zonesIn", zoneIds);
return listBy(sc); 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);
}
} }

View File

@ -22,6 +22,8 @@ import java.util.Map;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.ScopeType; import com.cloud.storage.ScopeType;
import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolStatus;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
/** /**
@ -139,4 +141,10 @@ public interface PrimaryDataStoreDao extends GenericDao<StoragePoolVO, Long> {
List<StoragePoolVO> findPoolsByStorageType(String storageType); List<StoragePoolVO> findPoolsByStorageType(String storageType);
List<StoragePoolVO> listStoragePoolsWithActiveVolumesByOfferingId(long offeringid); 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);
} }

View File

@ -20,12 +20,16 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import com.cloud.host.Status; import com.cloud.host.Status;
@ -57,6 +61,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
private final SearchBuilder<StoragePoolVO> DcLocalStorageSearch; private final SearchBuilder<StoragePoolVO> DcLocalStorageSearch;
private final GenericSearchBuilder<StoragePoolVO, Long> StatusCountSearch; private final GenericSearchBuilder<StoragePoolVO, Long> StatusCountSearch;
private final SearchBuilder<StoragePoolVO> ClustersSearch; private final SearchBuilder<StoragePoolVO> ClustersSearch;
private final SearchBuilder<StoragePoolVO> IdsSearch;
@Inject @Inject
private StoragePoolDetailsDao _detailsDao; private StoragePoolDetailsDao _detailsDao;
@ -143,6 +148,11 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
ClustersSearch = createSearchBuilder(); ClustersSearch = createSearchBuilder();
ClustersSearch.and("clusterIds", ClustersSearch.entity().getClusterId(), Op.IN); ClustersSearch.and("clusterIds", ClustersSearch.entity().getClusterId(), Op.IN);
ClustersSearch.and("status", ClustersSearch.entity().getStatus(), Op.EQ); 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); 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;
}
} }

View File

@ -84,7 +84,7 @@ SELECT
FROM FROM
`cloud`.`service_offering` `cloud`.`service_offering`
INNER JOIN 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 LEFT JOIN
`cloud`.`service_offering_details` AS `domain_details` ON `domain_details`.`service_offering_id` = `service_offering`.`id` AND `domain_details`.`name`='domainid' `cloud`.`service_offering_details` AS `domain_details` ON `domain_details`.`service_offering_id` = `service_offering`.`id` AND `domain_details`.`name`='domainid'
LEFT JOIN LEFT JOIN

View File

@ -81,6 +81,7 @@ public class Attribute {
protected String table; protected String table;
protected String columnName; protected String columnName;
protected Object value;
protected Field field; protected Field field;
protected int flags; protected int flags;
protected Column column; protected Column column;
@ -100,6 +101,10 @@ public class Attribute {
this.column = null; this.column = null;
} }
public Attribute(Object value) {
this.value = value;
}
protected void setupColumnInfo(Class<?> clazz, AttributeOverride[] overrides, String tableName, boolean isEmbedded, boolean isId) { protected void setupColumnInfo(Class<?> clazz, AttributeOverride[] overrides, String tableName, boolean isEmbedded, boolean isId) {
flags = Flag.Selectable.setTrue(flags); flags = Flag.Selectable.setTrue(flags);
GeneratedValue gv = field.getAnnotation(GeneratedValue.class); GeneratedValue gv = field.getAnnotation(GeneratedValue.class);
@ -214,6 +219,10 @@ public class Attribute {
return field; return field;
} }
public Object getValue() {
return value;
}
public Object get(Object entity) { public Object get(Object entity) {
try { try {
return field.get(entity); return field.get(entity);

View File

@ -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); Pair<List<T>, Integer> searchAndDistinctCount(final SearchCriteria<T> sc, final Filter filter, final String[] distinctColumns);
Integer countAll(); Integer countAll();
List<T> findByUuids(String... uuidArray);
} }

View File

@ -56,6 +56,7 @@ import javax.persistence.Enumerated;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.TableGenerator; import javax.persistence.TableGenerator;
import com.amazonaws.util.CollectionUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.utils.DateUtil; import com.cloud.utils.DateUtil;
@ -373,10 +374,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
} }
Collection<JoinBuilder<SearchCriteria<?>>> joins = null; Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
List<Attribute> joinAttrList = null;
if (sc != null) { if (sc != null) {
joins = sc.getJoins(); joins = sc.getJoins();
if (joins != null) { 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 { try {
pstmt = txn.prepareAutoCloseStatement(sql); pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1; int i = 1;
if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
for (Attribute attr : joinAttrList) {
prepareAttribute(i++, pstmt, attr, null);
}
}
if (clause != null) { if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) { for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second()); 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; Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
joins = sc.getJoins(); joins = sc.getJoins();
List<Attribute> joinAttrList = null;
if (joins != null) { if (joins != null) {
addJoins(str, joins); joinAttrList = addJoins(str, joins);
} }
List<Object> groupByValues = addGroupBy(str, sc); List<Object> groupByValues = addGroupBy(str, sc);
@ -462,6 +472,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
try { try {
pstmt = txn.prepareAutoCloseStatement(sql); pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1; int i = 1;
if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
for (Attribute attr : joinAttrList) {
prepareAttribute(i++, pstmt, attr, null);
}
}
if (clause != null) { if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) { for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second()); prepareAttribute(i++, pstmt, value.first(), value.second());
@ -1272,12 +1289,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
} }
@DB() @DB()
protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) { protected List<Attribute> addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
addJoins(str, joins, new HashMap<>()); return addJoins(str, joins, new HashMap<>());
} }
@DB() @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; boolean hasWhereClause = true;
int fromIndex = str.lastIndexOf("WHERE"); int fromIndex = str.lastIndexOf("WHERE");
if (fromIndex == -1) { if (fromIndex == -1) {
@ -1288,8 +1306,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
} }
for (JoinBuilder<SearchCriteria<?>> join : joins) { for (JoinBuilder<SearchCriteria<?>> join : joins) {
String joinTableName = join.getSecondAttribute().table; String joinTableName = join.getSecondAttribute()[0].table;
String joinTableAlias = findNextJoinTableName(joinTableName, joinedTableNames); String joinTableAlias;
if (StringUtils.isNotEmpty(join.getName())) {
joinTableAlias = join.getName();
joinedTableNames.put(joinTableName, joinTableAlias);
} else {
joinTableAlias = joinedTableNames.getOrDefault(joinTableName, joinTableName);
}
StringBuilder onClause = new StringBuilder(); StringBuilder onClause = new StringBuilder();
onClause.append(" ") onClause.append(" ")
.append(join.getType().getName()) .append(join.getType().getName())
@ -1298,21 +1322,36 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
if (!joinTableAlias.equals(joinTableName)) { if (!joinTableAlias.equals(joinTableName)) {
onClause.append(" ").append(joinTableAlias); onClause.append(" ").append(joinTableAlias);
} }
onClause.append(" ON ") onClause.append(" ON ");
.append(join.getFirstAttribute().table) for (int i = 0; i < join.getFirstAttributes().length; i++) {
.append(".") if (i > 0) {
.append(join.getFirstAttribute().columnName) onClause.append(join.getCondition().getName());
.append("="); }
if(!joinTableAlias.equals(joinTableName)) { if (join.getFirstAttributes()[i].getValue() != null) {
onClause.append(joinTableAlias); onClause.append("?");
} else { joinAttrList.add(join.getFirstAttributes()[i]);
onClause.append(joinTableName); } 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(".") onClause.append(" ");
.append(join.getSecondAttribute().columnName)
.append(" ");
str.insert(fromIndex, onClause); str.insert(fromIndex, onClause);
String whereClause = join.getT().getWhereClause(); String whereClause = join.getT().getWhereClause(joinTableAlias);
if (StringUtils.isNotEmpty(whereClause)) { if (StringUtils.isNotEmpty(whereClause)) {
if (!hasWhereClause) { if (!hasWhereClause) {
str.append(" WHERE "); str.append(" WHERE ");
@ -1329,20 +1368,10 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
for (JoinBuilder<SearchCriteria<?>> join : joins) { for (JoinBuilder<SearchCriteria<?>> join : joins) {
if (join.getT().getJoins() != null) { if (join.getT().getJoins() != null) {
addJoins(str, join.getT().getJoins(), joinedTableNames); joinAttrList.addAll(addJoins(str, join.getT().getJoins(), joinedTableNames));
} }
} }
} return joinAttrList;
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;
} }
private void removeAndClause(StringBuilder sql) { private void removeAndClause(StringBuilder sql) {
@ -1595,10 +1624,24 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
return; return;
} }
} }
if (attr.field.getType() == String.class) { if (attr.getValue() != null && attr.getValue() instanceof String) {
final String str = (String)value; pstmt.setString(j, (String)attr.getValue());
if (str == null) { } else if (attr.getValue() != null && attr.getValue() instanceof Long) {
pstmt.setString(j, null); 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; return;
} }
final Column column = attr.field.getAnnotation(Column.class); 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; Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
List<Attribute> joinAttrList = null;
if (sc != null) { if (sc != null) {
joins = sc.getJoins(); joins = sc.getJoins();
if (joins != null) { 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 { try {
pstmt = txn.prepareAutoCloseStatement(sql); pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1; int i = 1;
if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
for (Attribute attr : joinAttrList) {
prepareAttribute(i++, pstmt, attr, null);
}
}
if (clause != null) { if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) { for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second()); 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; Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
List<Attribute> joinAttrList = null;
if (sc != null) { if (sc != null) {
joins = sc.getJoins(); joins = sc.getJoins();
if (joins != null) { 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)) { try (PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql)) {
int i = 1; int i = 1;
if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
for (Attribute attr : joinAttrList) {
prepareAttribute(i++, pstmt, attr, null);
}
}
if (clause != null) { if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) { for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second()); prepareAttribute(i++, pstmt, value.first(), value.second());
@ -2119,6 +2178,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
return getCount(null); 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) { public Integer getCount(SearchCriteria<T> sc) {
sc = checkAndSetRemovedIsNull(sc); sc = checkAndSetRemovedIsNull(sc);
return getCountIncludingRemoved(sc); return getCountIncludingRemoved(sc);
@ -2136,10 +2202,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
} }
Collection<JoinBuilder<SearchCriteria<?>>> joins = null; Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
List<Attribute> joinAttrList = null;
if (sc != null) { if (sc != null) {
joins = sc.getJoins(); joins = sc.getJoins();
if (joins != null) { 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 { try {
pstmt = txn.prepareAutoCloseStatement(sql); pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1; int i = 1;
if (!CollectionUtils.isNullOrEmpty(joinAttrList)) {
for (Attribute attr : joinAttrList) {
prepareAttribute(i++, pstmt, attr, null);
}
}
if (clause != null) { if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) { for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second()); prepareAttribute(i++, pstmt, value.first(), value.second());

View File

@ -80,6 +80,12 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return this; 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 * Adds an AND condition. Some prefer this method because it looks like
* the actual SQL query. * the actual SQL query.
@ -134,6 +140,12 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return this; 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) { protected Preset left(Object field, Op op) {
Condition condition = constructCondition(UUID.randomUUID().toString(), " ( ", _specifiedAttrs.get(0), op); Condition condition = constructCondition(UUID.randomUUID().toString(), " ( ", _specifiedAttrs.get(0), op);
return new Preset(this, condition); return new Preset(this, condition);
@ -169,6 +181,10 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return left(field, op, name); 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. * Adds an OR condition to the SearchBuilder.
* *
@ -182,6 +198,12 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return this; 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 * Adds an OR condition
* *

View File

@ -31,19 +31,57 @@ public class JoinBuilder<T> {
return _name; 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 T t;
private final String name;
private JoinType type; 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.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.secondAttribute = secondAttribute;
this.type = type; 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() { public T getT() {
return t; return t;
} }
@ -56,19 +94,23 @@ public class JoinBuilder<T> {
this.type = type; this.type = type;
} }
public Attribute getFirstAttribute() { public JoinCondition getCondition() {
return firstAttribute; return condition;
} }
public void setFirstAttribute(Attribute firstAttribute) { public Attribute[] getFirstAttributes() {
this.firstAttribute = firstAttribute; return firstAttributes;
} }
public Attribute getSecondAttribute() { public void setFirstAttributes(Attribute[] firstAttributes) {
this.firstAttributes = firstAttributes;
}
public Attribute[] getSecondAttribute() {
return secondAttribute; return secondAttribute;
} }
public void setSecondAttribute(Attribute secondAttribute) { public void setSecondAttribute(Attribute[] secondAttribute) {
this.secondAttribute = secondAttribute; this.secondAttribute = secondAttribute;
} }

View File

@ -36,6 +36,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.MethodProxy;
import org.apache.commons.lang3.StringUtils;
/** /**
* SearchBase contains the methods that are used to build up search * 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); 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) { protected void init(final Class<T> entityType, final Class<K> resultType) {
_dao = (GenericDaoBase<? extends T, ? extends Serializable>)GenericDaoBase.getDao(entityType); _dao = (GenericDaoBase<? extends T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
if (_dao == null) { if (_dao == null) {
@ -194,15 +203,45 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
* @param joinType type of join * @param joinType type of join
* @return itself * @return itself
*/ */
@SuppressWarnings("unchecked")
public J join(final String name, final SearchBase<?, ?, ?> builder, final Object joinField1, final Object joinField2, final JoinBuilder.JoinType joinType) { 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"; if (_specifiedAttrs.size() != 1)
assert _specifiedAttrs.size() == 1 : "You didn't select the attribute."; throw new CloudRuntimeException("You didn't select the attribute.");
assert builder._entity != null : "SearchBuilder cannot be modified once it has been setup"; if (builder._specifiedAttrs.size() != 1)
assert builder._specifiedAttrs.size() == 1 : "You didn't select the attribute."; throw new CloudRuntimeException("You didn't select the attribute.");
assert builder != this : "You can't add yourself, can you? Really think about it!";
final JoinBuilder<SearchBase<?, ?, ?>> t = new JoinBuilder<SearchBase<?, ?, ?>>(builder, _specifiedAttrs.get(0), builder._specifiedAttrs.get(0), joinType); return join(name, builder, joinType, null, joinField1, joinField2);
}
/**
* 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) { if (_joins == null) {
_joins = new HashMap<String, JoinBuilder<SearchBase<?, ?, ?>>>(); _joins = new HashMap<String, JoinBuilder<SearchBase<?, ?, ?>>>();
} }
@ -223,6 +262,16 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
_specifiedAttrs.add(attr); _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 * @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. * 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; 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 _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 == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
assert op != Op.SC : "Call join"; assert op != Op.SC : "Call join";
final Condition condition = new Condition(conditionName, cond, attr, op); final Condition condition = new Condition(conditionName, cond, attr, op);
if (StringUtils.isNotEmpty(joinName)) {
condition.setJoinName(joinName);
}
_conditions.add(condition); _conditions.add(condition);
_specifiedAttrs.clear(); _specifiedAttrs.clear();
return condition; 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. * 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 static class Condition {
protected final String name; protected final String name;
protected final String cond; protected final String cond;
protected String joinName;
protected final Op op; protected final Op op;
protected final Attribute attr; protected final Attribute attr;
protected Object[] presets; protected Object[] presets;
@ -388,11 +447,15 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
this.presets = presets; this.presets = presets;
} }
public void setJoinName(final String joinName) {
this.joinName = joinName;
}
public Object[] getPresets() { public Object[] getPresets() {
return presets; 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) { if (count > 0) {
sql.append(cond); 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(" 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) { if (op == Op.IN && params.length == 1) {
sql.delete(sql.length() - op.toString().length(), sql.length()); sql.delete(sql.length() - op.toString().length(), sql.length());
sql.append("=?"); 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); final String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
set(fieldName); set(fieldName);
return null; return null;
} else if (name.equals("setLong") || name.equals("setString")) {
setAttr(args[0]);
} else { } else {
final Column ann = method.getAnnotation(Column.class); final Column ann = method.getAnnotation(Column.class);
if (ann != null) { if (ann != null) {

View File

@ -106,7 +106,7 @@ public class SearchCriteria<K> {
for (Map.Entry<String, JoinBuilder<SearchBase<?, ?, ?>>> entry : sb._joins.entrySet()) { for (Map.Entry<String, JoinBuilder<SearchBase<?, ?, ?>>> entry : sb._joins.entrySet()) {
JoinBuilder<SearchBase<?, ?, ?>> value = entry.getValue(); JoinBuilder<SearchBase<?, ?, ?>> value = entry.getValue();
_joins.put(entry.getKey(), _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; _selects = sb._selects;
@ -250,7 +250,7 @@ public class SearchCriteria<K> {
_additionals.add(condition); _additionals.add(condition);
} }
public String getWhereClause() { public String getWhereClause(String tableAlias) {
StringBuilder sql = new StringBuilder(); StringBuilder sql = new StringBuilder();
int i = 0; int i = 0;
for (Condition condition : _conditions) { for (Condition condition : _conditions) {
@ -259,7 +259,7 @@ public class SearchCriteria<K> {
} }
Object[] params = _params.get(condition.name); Object[] params = _params.get(condition.name);
if ((condition.op == null || condition.op.params == 0) || (params != null)) { 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); Object[] params = _params.get(condition.name);
if ((condition.op.params == 0) || (params != null)) { if ((condition.op.params == 0) || (params != null)) {
condition.toSql(sql, params, i++); condition.toSql(sql, tableAlias, params, i++);
} }
} }
return sql.toString(); return sql.toString();
} }
public String getWhereClause() {
return getWhereClause(null);
}
public List<Pair<Attribute, Object>> getValues() { public List<Pair<Attribute, Object>> getValues() {
ArrayList<Pair<Attribute, Object>> params = new ArrayList<Pair<Attribute, Object>>(_params.size()); ArrayList<Pair<Attribute, Object>> params = new ArrayList<Pair<Attribute, Object>>(_params.size());
for (Condition condition : _conditions) { for (Condition condition : _conditions) {

View File

@ -20,8 +20,6 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -229,12 +227,16 @@ public class GenericDaoBaseTest {
Attribute attr2 = new Attribute("table2", "column2"); Attribute attr2 = new Attribute("table2", "column2");
Attribute attr3 = new Attribute("table3", "column1"); Attribute attr3 = new Attribute("table3", "column1");
Attribute attr4 = new Attribute("table4", "column2"); 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(), attr1, attr2, JoinBuilder.JoinType.INNER));
joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), attr3, attr4, 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); 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 @Test
@ -248,22 +250,17 @@ public class GenericDaoBaseTest {
Attribute tBc2 = new Attribute("tableB", "column2"); Attribute tBc2 = new Attribute("tableB", "column2");
Attribute tCc3 = new Attribute("tableC", "column3"); Attribute tCc3 = new Attribute("tableC", "column3");
Attribute tDc4 = new Attribute("tableD", "column4"); 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<>("tableA1Alias", dbTestDao.createSearchCriteria(), tBc2, tAc1, JoinBuilder.JoinType.INNER));
joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tCc3, tAc2, JoinBuilder.JoinType.INNER)); joins.add(new JoinBuilder<>("tableA2Alias", dbTestDao.createSearchCriteria(), tCc3, tAc2, JoinBuilder.JoinType.INNER));
joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tDc4, tAc3, 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); 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()); 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());
@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));
} }
} }

View File

@ -27,10 +27,12 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.dc.ClusterVO;
import com.cloud.utils.Ternary; import com.cloud.utils.Ternary;
import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.ListClustersMetricsCmd; import org.apache.cloudstack.api.ListClustersMetricsCmd;
@ -634,6 +636,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
@Override @Override
public List<StoragePoolMetricsResponse> listStoragePoolMetrics(List<StoragePoolResponse> poolResponses) { public List<StoragePoolMetricsResponse> listStoragePoolMetrics(List<StoragePoolResponse> poolResponses) {
final List<StoragePoolMetricsResponse> metricsResponses = new ArrayList<>(); 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) { for (final StoragePoolResponse poolResponse: poolResponses) {
StoragePoolMetricsResponse metricsResponse = new StoragePoolMetricsResponse(); 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"); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate storagepool metrics response");
} }
Long poolClusterId = null; Long poolClusterId = clusterUuidToIdMap.get(poolResponse.getClusterId());
final Cluster cluster = clusterDao.findByUuid(poolResponse.getClusterId());
if (cluster != null) {
poolClusterId = cluster.getId();
}
final Double storageThreshold = AlertManager.StorageCapacityThreshold.valueIn(poolClusterId); final Double storageThreshold = AlertManager.StorageCapacityThreshold.valueIn(poolClusterId);
final Double storageDisableThreshold = CapacityManager.StorageCapacityDisableThreshold.valueIn(poolClusterId); final Double storageDisableThreshold = CapacityManager.StorageCapacityDisableThreshold.valueIn(poolClusterId);

View File

@ -17,12 +17,15 @@
package com.cloud.api; package com.cloud.api;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
@ -2082,6 +2085,29 @@ public class ApiDBUtils {
return response; 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) { public static AccountJoinVO newAccountView(Account e) {
return s_accountJoinDao.newAccountView(e); return s_accountJoinDao.newAccountView(e);
} }

File diff suppressed because it is too large Load Diff

View File

@ -541,11 +541,7 @@ public class ViewResponseHelper {
} }
public static List<AccountResponse> createAccountResponse(ResponseView view, EnumSet<DomainDetails> details, AccountJoinVO... accounts) { public static List<AccountResponse> createAccountResponse(ResponseView view, EnumSet<DomainDetails> details, AccountJoinVO... accounts) {
List<AccountResponse> respList = new ArrayList<AccountResponse>(); return ApiDBUtils.newAccountResponses(view, details, accounts);
for (AccountJoinVO vt : accounts){
respList.add(ApiDBUtils.newAccountResponse(view, details, vt));
}
return respList;
} }
public static List<AsyncJobResponse> createAsyncJobResponse(AsyncJobJoinVO... jobs) { public static List<AsyncJobResponse> createAsyncJobResponse(AsyncJobJoinVO... jobs) {

View File

@ -17,6 +17,7 @@
package com.cloud.api.query.dao; package com.cloud.api.query.dao;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import org.apache.cloudstack.api.ApiConstants.DomainDetails; import org.apache.cloudstack.api.ApiConstants.DomainDetails;
import org.apache.cloudstack.api.ResponseObject.ResponseView; 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); void setResourceLimits(AccountJoinVO account, boolean accountIsAdmin, ResourceLimitAndCountResponse response);
List<AccountJoinVO> searchByIds(Long... ids);
} }

View File

@ -16,11 +16,13 @@
// under the License. // under the License.
package com.cloud.api.query.dao; package com.cloud.api.query.dao;
import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; 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 class AccountJoinDaoImpl extends GenericDaoBase<AccountJoinVO, Long> implements AccountJoinDao {
public static final Logger s_logger = Logger.getLogger(AccountJoinDaoImpl.class); public static final Logger s_logger = Logger.getLogger(AccountJoinDaoImpl.class);
@Inject
private ConfigurationDao configDao;
private final SearchBuilder<AccountJoinVO> acctIdSearch; private final SearchBuilder<AccountJoinVO> acctIdSearch;
private final SearchBuilder<AccountJoinVO> domainSearch;
@Inject @Inject
AccountManager _acctMgr; AccountManager _acctMgr;
protected AccountJoinDaoImpl() { protected AccountJoinDaoImpl() {
domainSearch = createSearchBuilder();
domainSearch.and("idIN", domainSearch.entity().getId(), SearchCriteria.Op.IN);
domainSearch.done();
acctIdSearch = createSearchBuilder(); acctIdSearch = createSearchBuilder();
acctIdSearch.and("id", acctIdSearch.entity().getId(), SearchCriteria.Op.EQ); acctIdSearch.and("id", acctIdSearch.entity().getId(), SearchCriteria.Op.EQ);
acctIdSearch.done(); acctIdSearch.done();
@ -232,6 +241,50 @@ public class AccountJoinDaoImpl extends GenericDaoBase<AccountJoinVO, Long> impl
response.setSecondaryStorageAvailable(secondaryStorageAvail); 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 @Override
public AccountJoinVO newAccountView(Account acct) { public AccountJoinVO newAccountView(Account acct) {
SearchCriteria<AccountJoinVO> sc = acctIdSearch.create(); SearchCriteria<AccountJoinVO> sc = acctIdSearch.create();

View File

@ -33,4 +33,6 @@ public interface DiskOfferingJoinDao extends GenericDao<DiskOfferingJoinVO, Long
DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO dof); DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO dof);
DiskOfferingJoinVO newDiskOfferingView(DiskOffering dof); DiskOfferingJoinVO newDiskOfferingView(DiskOffering dof);
List<DiskOfferingJoinVO> searchByIds(Long... idArray);
} }

View File

@ -16,6 +16,7 @@
// under the License. // under the License.
package com.cloud.api.query.dao; package com.cloud.api.query.dao;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; 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.ApiConstants;
import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -51,9 +53,12 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO,
@Inject @Inject
private AnnotationDao annotationDao; private AnnotationDao annotationDao;
@Inject @Inject
private ConfigurationDao configDao;
@Inject
private AccountManager accountManager; private AccountManager accountManager;
private final SearchBuilder<DiskOfferingJoinVO> dofIdSearch; private final SearchBuilder<DiskOfferingJoinVO> dofIdSearch;
private SearchBuilder<DiskOfferingJoinVO> diskOfferingSearch;
private final Attribute _typeAttr; private final Attribute _typeAttr;
protected DiskOfferingJoinDaoImpl() { protected DiskOfferingJoinDaoImpl() {
@ -62,6 +67,11 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO,
dofIdSearch.and("id", dofIdSearch.entity().getId(), SearchCriteria.Op.EQ); dofIdSearch.and("id", dofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
dofIdSearch.done(); dofIdSearch.done();
diskOfferingSearch = createSearchBuilder();
diskOfferingSearch.and("idIN", diskOfferingSearch.entity().getId(), SearchCriteria.Op.IN);
diskOfferingSearch.done();
_typeAttr = _allAttributes.get("type"); _typeAttr = _allAttributes.get("type");
_count = "select count(distinct id) from disk_offering_view WHERE "; _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(); assert offerings != null && offerings.size() == 1 : "No disk offering found for offering id " + offering.getId();
return offerings.get(0); 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;
}
} }

View File

@ -17,6 +17,7 @@
package com.cloud.api.query.dao; package com.cloud.api.query.dao;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import org.apache.cloudstack.api.ApiConstants.DomainDetails; import org.apache.cloudstack.api.ApiConstants.DomainDetails;
import org.apache.cloudstack.api.ResponseObject.ResponseView; 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); void setResourceLimits(DomainJoinVO domain, boolean isRootDomain, ResourceLimitAndCountResponse response);
List<DomainJoinVO> searchByIds(Long... domainIds);
} }

View File

@ -16,6 +16,7 @@
// under the License. // under the License.
package com.cloud.api.query.dao; package com.cloud.api.query.dao;
import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; 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.DomainResponse;
import org.apache.cloudstack.api.response.ResourceLimitAndCountResponse; import org.apache.cloudstack.api.response.ResourceLimitAndCountResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; 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); public static final Logger s_logger = Logger.getLogger(DomainJoinDaoImpl.class);
private SearchBuilder<DomainJoinVO> domainIdSearch; private SearchBuilder<DomainJoinVO> domainIdSearch;
private SearchBuilder<DomainJoinVO> domainSearch;
@Inject @Inject
private AnnotationDao annotationDao; private AnnotationDao annotationDao;
@Inject @Inject
private ConfigurationDao configDao;
@Inject
private AccountManager accountManager; private AccountManager accountManager;
protected DomainJoinDaoImpl() { protected DomainJoinDaoImpl() {
@ -59,6 +64,10 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
domainIdSearch.and("id", domainIdSearch.entity().getId(), SearchCriteria.Op.EQ); domainIdSearch.and("id", domainIdSearch.entity().getId(), SearchCriteria.Op.EQ);
domainIdSearch.done(); 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 "; 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); 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 @Override
public DomainJoinVO newDomainView(Domain domain) { public DomainJoinVO newDomainView(Domain domain) {
SearchCriteria<DomainJoinVO> sc = domainIdSearch.create(); SearchCriteria<DomainJoinVO> sc = domainIdSearch.create();

View File

@ -34,4 +34,5 @@ public interface ServiceOfferingJoinDao extends GenericDao<ServiceOfferingJoinVO
ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering); ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering);
Map<Long, List<String>> listDomainsOfServiceOfferingsUsedByDomainPath(String domainPath); Map<Long, List<String>> listDomainsOfServiceOfferingsUsedByDomainPath(String domainPath);
List<ServiceOfferingJoinVO> searchByIds(Long... id);
} }

View File

@ -21,6 +21,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -34,6 +35,7 @@ import com.cloud.storage.DiskOfferingVO;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -56,10 +58,14 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
@Inject @Inject
private AnnotationDao annotationDao; private AnnotationDao annotationDao;
@Inject @Inject
private ConfigurationDao configDao;
@Inject
private AccountManager accountManager; private AccountManager accountManager;
private SearchBuilder<ServiceOfferingJoinVO> sofIdSearch; private SearchBuilder<ServiceOfferingJoinVO> sofIdSearch;
private SearchBuilder<ServiceOfferingJoinVO> srvOfferingSearch;
/** /**
* Constant used to convert GB into Bytes (or the other way around). * Constant used to convert GB into Bytes (or the other way around).
* GB * MB * KB = Bytes // * GB * MB * KB = Bytes //
@ -85,6 +91,10 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
sofIdSearch.and("id", sofIdSearch.entity().getId(), SearchCriteria.Op.EQ); sofIdSearch.and("id", sofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
sofIdSearch.done(); 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 "; 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); return offerings.get(0);
} }
@Override @Override
public Map<Long, List<String>> listDomainsOfServiceOfferingsUsedByDomainPath(String domainPath) { 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)); 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<>(); 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;
}
} }

View File

@ -19,9 +19,6 @@ package com.cloud.api.query.dao;
import java.util.List; import java.util.List;
import com.cloud.storage.ScopeType; 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 org.apache.cloudstack.api.response.StoragePoolResponse;
import com.cloud.api.query.vo.StoragePoolJoinVO; import com.cloud.api.query.vo.StoragePoolJoinVO;
@ -43,8 +40,6 @@ public interface StoragePoolJoinDao extends GenericDao<StoragePoolJoinVO, Long>
List<StoragePoolJoinVO> searchByIds(Long... spIds); 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); List<StoragePoolVO> findStoragePoolByScopeAndRuleTags(Long datacenterId, Long podId, Long clusterId, ScopeType scopeType, List<String> tags);
} }

View File

@ -23,13 +23,10 @@ import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ScopeType; import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.StorageStats; import com.cloud.storage.StorageStats;
import com.cloud.storage.VolumeApiServiceImpl; import com.cloud.storage.VolumeApiServiceImpl;
import com.cloud.user.AccountManager; import com.cloud.user.AccountManager;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils; import com.cloud.utils.StringUtils;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria;
@ -311,77 +308,6 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase<StoragePoolJoinVO, Lo
return uvList; 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 @Override
public List<StoragePoolVO> findStoragePoolByScopeAndRuleTags(Long datacenterId, Long podId, Long clusterId, ScopeType scopeType, List<String> tags) { public List<StoragePoolVO> findStoragePoolByScopeAndRuleTags(Long datacenterId, Long podId, Long clusterId, ScopeType scopeType, List<String> tags) {
SearchCriteria<StoragePoolJoinVO> sc = findByDatacenterAndScopeSb.create(); SearchCriteria<StoragePoolJoinVO> sc = findByDatacenterAndScopeSb.create();

View File

@ -198,11 +198,15 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
List<ImageStoreVO> storesInZone = dataStoreDao.listStoresByZoneId(template.getDataCenterId()); List<ImageStoreVO> storesInZone = dataStoreDao.listStoresByZoneId(template.getDataCenterId());
Long[] storeIds = storesInZone.stream().map(ImageStoreVO::getId).toArray(Long[]::new); Long[] storeIds = storesInZone.stream().map(ImageStoreVO::getId).toArray(Long[]::new);
List<TemplateDataStoreVO> templatesInStore = _templateStoreDao.listByTemplateNotBypassed(template.getId(), storeIds); 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<>(); List<Map<String, String>> downloadProgressDetails = new ArrayList<>();
HashMap<String, String> downloadDetailInImageStores = null; HashMap<String, String> downloadDetailInImageStores = null;
for (TemplateDataStoreVO templateInStore : templatesInStore) { for (TemplateDataStoreVO templateInStore : templatesInStore) {
downloadDetailInImageStores = new HashMap<>(); downloadDetailInImageStores = new HashMap<>();
ImageStoreVO imageStore = dataStoreDao.findById(templateInStore.getDataStoreId()); ImageStoreVO imageStore = imageStoreMap.get(templateInStore.getDataStoreId());
if (imageStore != null) { if (imageStore != null) {
downloadDetailInImageStores.put("datastore", imageStore.getName()); downloadDetailInImageStores.put("datastore", imageStore.getName());
if (view.equals(ResponseView.Full)) { 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<Long> poolIds = poolsInZone.stream().map(StoragePoolVO::getId).collect(Collectors.toList());
List<VMTemplateStoragePoolVO> templatesInPool = templatePoolDao.listByTemplateId(template.getId(), poolIds); 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) { for (VMTemplateStoragePoolVO templateInPool : templatesInPool) {
downloadDetailInImageStores = new HashMap<>(); downloadDetailInImageStores = new HashMap<>();
StoragePoolVO storagePool = primaryDataStoreDao.findById(templateInPool.getDataStoreId()); StoragePoolVO storagePool = storagePoolMap.get(templateInPool.getDataStoreId());
if (storagePool != null) { if (storagePool != null) {
downloadDetailInImageStores.put("datastore", storagePool.getName()); downloadDetailInImageStores.put("datastore", storagePool.getName());
if (view.equals(ResponseView.Full)) { if (view.equals(ResponseView.Full)) {

View File

@ -7497,7 +7497,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
networkRate = offering.getRateMbps(); networkRate = offering.getRateMbps();
} else { } else {
// for domain router service offering, get network rate from // 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); networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(dataCenterId);
} else { } else {
networkRate = Integer.parseInt(_configDao.getValue(Config.VmNetworkThrottlingRate.key())); networkRate = Integer.parseInt(_configDao.getValue(Config.VmNetworkThrottlingRate.key()));

View File

@ -4286,9 +4286,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
} }
final String virtualMachineDomainRouterType = VirtualMachine.Type.DomainRouter.toString(); 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 " 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()));
} }
} }

View File

@ -94,7 +94,7 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
} }
@Override @Override
public Role findRole(Long id, boolean removePrivateRoles) { public Role findRole(Long id, boolean ignorePrivateRoles) {
if (id == null || id < 1L) { if (id == null || id < 1L) {
logger.trace(String.format("Role ID is invalid [%s]", id)); logger.trace(String.format("Role ID is invalid [%s]", id));
return null; return null;
@ -104,13 +104,36 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
logger.trace(String.format("Role not found [id=%s]", id)); logger.trace(String.format("Role not found [id=%s]", id));
return null; 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())); 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 null;
} }
return role; 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 @Override
public Role findRole(Long id) { public Role findRole(Long id) {
return findRole(id, false); return findRole(id, false);

View File

@ -20,6 +20,8 @@ package com.cloud.api.query;
import com.cloud.api.query.dao.TemplateJoinDao; import com.cloud.api.query.dao.TemplateJoinDao;
import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.TemplateJoinVO; 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.event.dao.EventJoinDao;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
@ -92,6 +94,9 @@ public class QueryManagerImplTest {
@Mock @Mock
AccountManager accountManager; AccountManager accountManager;
@Mock
EventDao eventDao;
@Mock @Mock
EventJoinDao eventJoinDao; EventJoinDao eventJoinDao;
@ -128,12 +133,12 @@ public class QueryManagerImplTest {
UUID.randomUUID().toString(), User.Source.UNKNOWN); UUID.randomUUID().toString(), User.Source.UNKNOWN);
CallContext.register(user, account); CallContext.register(user, account);
Mockito.when(accountManager.isRootAdmin(account.getId())).thenReturn(false); Mockito.when(accountManager.isRootAdmin(account.getId())).thenReturn(false);
final SearchBuilder<EventJoinVO> searchBuilder = Mockito.mock(SearchBuilder.class); final SearchBuilder<EventVO> eventSearchBuilder = Mockito.mock(SearchBuilder.class);
final SearchCriteria<EventJoinVO> searchCriteria = Mockito.mock(SearchCriteria.class); final SearchCriteria<EventVO> eventSearchCriteria = Mockito.mock(SearchCriteria.class);
final EventJoinVO eventJoinVO = Mockito.mock(EventJoinVO.class); final EventVO eventVO = Mockito.mock(EventVO.class);
when(searchBuilder.entity()).thenReturn(eventJoinVO); when(eventSearchBuilder.entity()).thenReturn(eventVO);
when(searchBuilder.create()).thenReturn(searchCriteria); when(eventSearchBuilder.create()).thenReturn(eventSearchCriteria);
Mockito.when(eventJoinDao.createSearchBuilder()).thenReturn(searchBuilder); Mockito.when(eventDao.createSearchBuilder()).thenReturn(eventSearchBuilder);
} }
private ListEventsCmd setupMockListEventsCmd() { private ListEventsCmd setupMockListEventsCmd() {
@ -149,19 +154,26 @@ public class QueryManagerImplTest {
String uuid = UUID.randomUUID().toString(); String uuid = UUID.randomUUID().toString();
Mockito.when(cmd.getResourceId()).thenReturn(uuid); Mockito.when(cmd.getResourceId()).thenReturn(uuid);
Mockito.when(cmd.getResourceType()).thenReturn(ApiCommandResourceType.Network.toString()); Mockito.when(cmd.getResourceType()).thenReturn(ApiCommandResourceType.Network.toString());
List<EventJoinVO> events = new ArrayList<>(); List<EventVO> events = new ArrayList<>();
events.add(Mockito.mock(EventJoinVO.class)); events.add(Mockito.mock(EventVO.class));
events.add(Mockito.mock(EventJoinVO.class)); events.add(Mockito.mock(EventVO.class));
events.add(Mockito.mock(EventJoinVO.class)); events.add(Mockito.mock(EventVO.class));
Pair<List<EventJoinVO>, Integer> pair = new Pair<>(events, events.size()); 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); NetworkVO network = Mockito.mock(NetworkVO.class);
Mockito.when(network.getId()).thenReturn(1L); Mockito.when(network.getId()).thenReturn(1L);
Mockito.when(network.getAccountId()).thenReturn(account.getId()); Mockito.when(network.getAccountId()).thenReturn(account.getId());
Mockito.when(entityManager.findByUuidIncludingRemoved(Network.class, uuid)).thenReturn(network); Mockito.when(entityManager.findByUuidIncludingRemoved(Network.class, uuid)).thenReturn(network);
Mockito.doNothing().when(accountManager).checkAccess(account, SecurityChecker.AccessType.ListEntry, true, 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>(); List<EventResponse> respList = new ArrayList<EventResponse>();
for (EventJoinVO vt : events) { for (EventJoinVO vt : eventJoins) {
respList.add(eventJoinDao.newEventResponse(vt)); respList.add(eventJoinDao.newEventResponse(vt));
} }
try (MockedStatic<ViewResponseHelper> ignored = Mockito.mockStatic(ViewResponseHelper.class)) { try (MockedStatic<ViewResponseHelper> ignored = Mockito.mockStatic(ViewResponseHelper.class)) {

View File

@ -789,10 +789,10 @@ public class NetworkServiceImplTest {
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenSystemVmTypeIsNotDomainRouter() { public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenSystemVmTypeIsNotDomainRouter() {
doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findById(anyLong()); doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findById(anyLong());
doReturn(ServiceOffering.State.Active).when(serviceOfferingVoMock).getState(); 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].", 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, () -> { InvalidParameterValueException assertThrows = Assert.assertThrows(expectedException, () -> {
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l); service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
}); });

View File

@ -297,6 +297,11 @@ public class MockUsageEventDao implements UsageEventDao{
return null; return null;
} }
@Override
public List<UsageEventVO> findByUuids(String... uuids) {
return null;
}
@Override @Override
public List<UsageEventVO> listLatestEvents(Date endDate) { public List<UsageEventVO> listLatestEvents(Date endDate) {
return null; return null;