Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ public class ApiConstants {
public static final String SESSIONKEY = "sessionkey";
public static final String SHOW_CAPACITIES = "showcapacities";
public static final String SHOW_REMOVED = "showremoved";
public static final String SHOW_UNIQUE = "showunique";
public static final String SIGNATURE = "signature";
public static final String SIGNATURE_VERSION = "signatureversion";
public static final String SIZE = "size";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd {
@Parameter(name=ApiConstants.SHOW_REMOVED, type=CommandType.BOOLEAN, description="show removed ISOs as well")
private Boolean showRemoved;

@Parameter(name = ApiConstants.SHOW_UNIQUE, type = CommandType.BOOLEAN, description = "If set to true, list only unique isos across zones", since = "4.13.2")
private Boolean showUnique;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -115,7 +118,11 @@ public Long getZoneId() {
}

public Boolean getShowRemoved() {
return (showRemoved != null ? showRemoved : false);
return showRemoved != null && showRemoved;
}

public Boolean getShowUnique() {
return showUnique != null && showUnique;
}

public boolean listInReadyState() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd {
@Parameter(name = ApiConstants.SHOW_REMOVED, type = CommandType.BOOLEAN, description = "show removed templates as well")
private Boolean showRemoved;

@Parameter(name = ApiConstants.SHOW_UNIQUE, type = CommandType.BOOLEAN, description = "If set to true, list only unique templates across zones", since = "4.13.2")
private Boolean showUnique;

@Parameter(name = ApiConstants.PARENT_TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "list datadisk templates by parent template id", since = "4.4")
private Long parentTemplateId;

Expand Down Expand Up @@ -103,7 +106,11 @@ public Long getZoneId() {
}

public Boolean getShowRemoved() {
return (showRemoved != null ? showRemoved : false);
return showRemoved != null && showRemoved;
}

public Boolean getShowUnique() {
return showUnique != null && showUnique;
}

public Long getParentTemplateId() {
Expand Down
54 changes: 35 additions & 19 deletions server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3154,12 +3154,12 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());

return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType,
showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl, cmd.getIds(), parentTemplateId);
showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl, cmd.getIds(), parentTemplateId, cmd.getShowUnique());
}

private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize,
Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List<Account> permittedAccounts, Account caller,
ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags, boolean showRemovedTmpl, List<Long> ids, Long parentTemplateId) {
ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags, boolean showRemovedTmpl, List<Long> ids, Long parentTemplateId, Boolean showUnique) {

// check if zone is configured, if not, just return empty list
List<HypervisorType> hypers = null;
Expand All @@ -3176,7 +3176,11 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", SortKeyAscending.value());

SearchBuilder<TemplateJoinVO> sb = _templateJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair
if (showUnique) {
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct templateId
} else {
sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair
}
if (ids != null && !ids.isEmpty()) {
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
}
Expand Down Expand Up @@ -3413,23 +3417,16 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter);
} else {
sc.addAnd("templateState", SearchCriteria.Op.IN, new State[] {State.Active, State.UploadAbandoned, State.UploadError, State.NotUploaded, State.UploadInProgress});
final String[] distinctColumns = {"temp_zone_pair"};
uniqueTmplPair = _templateJoinDao.searchAndDistinctCount(sc, searchFilter, distinctColumns);
if (showUnique) {
final String[] distinctColumns = {"id"};
uniqueTmplPair = _templateJoinDao.searchAndDistinctCount(sc, searchFilter, distinctColumns);
} else {
final String[] distinctColumns = {"temp_zone_pair"};
uniqueTmplPair = _templateJoinDao.searchAndDistinctCount(sc, searchFilter, distinctColumns);
}
}

Integer count = uniqueTmplPair.second();
if (count.intValue() == 0) {
// empty result
return uniqueTmplPair;
}
List<TemplateJoinVO> uniqueTmpls = uniqueTmplPair.first();
String[] tzIds = new String[uniqueTmpls.size()];
int i = 0;
for (TemplateJoinVO v : uniqueTmpls) {
tzIds[i++] = v.getTempZonePair();
}
List<TemplateJoinVO> vrs = _templateJoinDao.searchByTemplateZonePair(showRemovedTmpl, tzIds);
return new Pair<List<TemplateJoinVO>, Integer>(vrs, count);
return findTemplatesByIdOrTempZonePair(uniqueTmplPair, showRemovedTmpl, showUnique);

// TODO: revisit the special logic for iso search in
// VMTemplateDaoImpl.searchForTemplates and understand why we need to
Expand All @@ -3438,6 +3435,25 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP

}

// findTemplatesByIdOrTempZonePair returns the templates with the given ids if showUnique is true, or else by the TempZonePair
private Pair<List<TemplateJoinVO>, Integer> findTemplatesByIdOrTempZonePair(Pair<List<TemplateJoinVO>, Integer> templateDataPair, boolean showRemoved, boolean showUnique) {
Integer count = templateDataPair.second();
if (count.intValue() == 0) {
// empty result
return templateDataPair;
}
List<TemplateJoinVO> templateData = templateDataPair.first();
List<TemplateJoinVO> templates = null;
if (showUnique) {
Long[] templateIds = templateData.stream().map(template -> template.getId()).toArray(Long[]::new);
templates = _templateJoinDao.findByDistinctIds(templateIds);
} else {
String[] templateZonePairs = templateData.stream().map(template -> template.getTempZonePair()).toArray(String[]::new);
templates = _templateJoinDao.searchByTemplateZonePair(showRemoved, templateZonePairs);
}
return new Pair<List<TemplateJoinVO>, Integer>(templates, count);
}

@Override
public ListResponse<TemplateResponse> listIsos(ListIsosCmd cmd) {
Pair<List<TemplateJoinVO>, Integer> result = searchForIsosInternal(cmd);
Expand Down Expand Up @@ -3480,7 +3496,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cm
HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());

return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(),
hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO, null, null);
hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO, null, null, cmd.getShowUnique());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,5 @@ public interface TemplateJoinDao extends GenericDao<TemplateJoinVO, Long> {

Pair<List<TemplateJoinVO>, Integer> searchIncludingRemovedAndCount(final SearchCriteria<TemplateJoinVO> sc, final Filter filter);

List<TemplateJoinVO> findByDistinctIds(Long... ids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa

private final SearchBuilder<TemplateJoinVO> tmpltIdSearch;

private final SearchBuilder<TemplateJoinVO> tmpltIdsSearch;

private final SearchBuilder<TemplateJoinVO> tmpltZoneSearch;

private final SearchBuilder<TemplateJoinVO> activeTmpltSearch;
Expand All @@ -88,6 +90,11 @@ protected TemplateJoinDaoImpl() {
tmpltIdSearch.and("id", tmpltIdSearch.entity().getId(), SearchCriteria.Op.EQ);
tmpltIdSearch.done();

tmpltIdsSearch = createSearchBuilder();
tmpltIdsSearch.and("idsIN", tmpltIdsSearch.entity().getId(), SearchCriteria.Op.IN);
tmpltIdsSearch.groupBy(tmpltIdsSearch.entity().getId());
tmpltIdsSearch.done();

tmpltZoneSearch = createSearchBuilder();
tmpltZoneSearch.and("id", tmpltZoneSearch.entity().getId(), SearchCriteria.Op.EQ);
tmpltZoneSearch.and("dataCenterId", tmpltZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
Expand Down Expand Up @@ -481,4 +488,14 @@ public Pair<List<TemplateJoinVO>, Integer> searchIncludingRemovedAndCount(final
return new Pair<List<TemplateJoinVO>, Integer>(objects, count);
}

@Override
public List<TemplateJoinVO> findByDistinctIds(Long... ids) {
if (ids == null || ids.length == 0) {
return new ArrayList<TemplateJoinVO>();
}
SearchCriteria<TemplateJoinVO> sc = tmpltIdsSearch.create();
sc.setParameters("idsIN", ids);
return searchIncludingRemoved(sc, null, null, false);
}

}