From 6a9d5a7a0d4f61839e038e2a39d89a4ed6180f5d Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Fri, 6 Jul 2012 16:37:16 -0700 Subject: [PATCH] ResourceTags: respect tag parameter in listTemplates/listIsos commands --- .../cloud/api/commands/ListTemplatesCmd.java | 1 - .../src/com/cloud/api/ApiResponseHelper.java | 19 +++++ .../cloud/server/ManagementServerImpl.java | 16 +++-- .../com/cloud/storage/StorageManagerImpl.java | 2 +- .../com/cloud/storage/dao/VMTemplateDao.java | 14 ++-- .../cloud/storage/dao/VMTemplateDaoImpl.java | 72 ++++++++++++++++--- setup/db/create-schema.sql | 5 +- 7 files changed, 104 insertions(+), 25 deletions(-) diff --git a/api/src/com/cloud/api/commands/ListTemplatesCmd.java b/api/src/com/cloud/api/commands/ListTemplatesCmd.java index 7df7cf64451..f80b0420dc5 100755 --- a/api/src/com/cloud/api/commands/ListTemplatesCmd.java +++ b/api/src/com/cloud/api/commands/ListTemplatesCmd.java @@ -19,7 +19,6 @@ import java.util.Set; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index ce3daa9ccd4..aeb9eb2f14b 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -2137,6 +2137,15 @@ public class ApiResponseHelper implements ResponseGenerator { Account owner = ApiDBUtils.findAccountById(iso.getAccountId()); populateAccount(isoResponse, owner.getId()); populateDomain(isoResponse, owner.getDomainId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + isoResponse.setTags(tagResponses); isoResponse.setObjectName("iso"); isoResponses.add(isoResponse); @@ -2285,6 +2294,16 @@ public class ApiResponseHelper implements ResponseGenerator { if (isoSize > 0) { isoResponse.setSize(isoSize); } + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); + + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + isoResponse.setTags(tagResponses); isoResponse.setObjectName("iso"); isoResponses.add(isoResponse); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 2f0f334ea9a..a731e94200e 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1292,12 +1292,15 @@ public class ManagementServerImpl implements ManagementServer { boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured)); HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); - return listTemplates(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, showDomr, + return listTemplates(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, + cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); } - private Set> listTemplates(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 permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { + private Set> listTemplates(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 permittedAccounts, Account caller, + ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { VMTemplateVO template = null; if (templateId != null) { @@ -1335,11 +1338,12 @@ public class ManagementServerImpl implements ManagementServer { if (template == null) { templateZonePairSet = _templateDao.searchSwiftTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, - permittedAccounts, caller); + permittedAccounts, caller, tags); Set> templateZonePairSet2 = new HashSet>(); templateZonePairSet2 = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, - permittedAccounts, caller, listProjectResourcesCriteria); + permittedAccounts, caller, listProjectResourcesCriteria, tags); + for (Pair tmpltPair : templateZonePairSet2) { if (!templateZonePairSet.contains(new Pair(tmpltPair.first(), -1L))) { templateZonePairSet.add(tmpltPair); @@ -1358,7 +1362,7 @@ public class ManagementServerImpl implements ManagementServer { if (template == null) { templateZonePairSet = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, - permittedAccounts, caller, listProjectResourcesCriteria); + permittedAccounts, caller, listProjectResourcesCriteria, tags); } else { // if template is not public, perform permission check here if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 21de0a75cbb..350a35d3ca1 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -3769,7 +3769,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag sb.join("vmSearch", vmSearch, sb.entity().getInstanceId(), vmSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER); if (tags != null && !tags.isEmpty()) { - SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); for (int count=0; count < tags.size(); count++) { tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); diff --git a/server/src/com/cloud/storage/dao/VMTemplateDao.java b/server/src/com/cloud/storage/dao/VMTemplateDao.java index dd97277e79d..351055f7ff4 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDao.java @@ -13,6 +13,7 @@ package com.cloud.storage.dao; import java.util.List; +import java.util.Map; import java.util.Set; import com.cloud.domain.DomainVO; @@ -43,17 +44,20 @@ public interface VMTemplateDao extends GenericDao { public List findIsosByIdAndPath(Long domainId, Long accountId, String path); public List listReadyTemplates(); public List listByAccountId(long accountId); - public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, - DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria); + public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, + List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, + HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, + ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags); - public Set> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, - Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller); + public Set> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, + boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, + Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, Map tags); public long addTemplateToZone(VMTemplateVO tmplt, long zoneId); public List listAllInZone(long dataCenterId); public List listByHypervisorType(List hyperTypes); - public List publicIsoSearch(Boolean bootable, boolean listRemoved); + public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags); VMTemplateVO findSystemVMTemplate(long zoneId); VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType); diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 9e71f082622..cae54bc265f 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -45,6 +45,7 @@ import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; +import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; import com.cloud.user.Account; @@ -133,8 +134,32 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } @Override - public List publicIsoSearch(Boolean bootable, boolean listRemoved){ - SearchCriteria sc = PublicIsoSearch.create(); + public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags){ + + SearchBuilder sb = null; + if (tags == null || tags.isEmpty()) { + sb = PublicIsoSearch; + } else { + sb = createSearchBuilder(); + sb.and("public", sb.entity().isPublicTemplate(), SearchCriteria.Op.EQ); + sb.and("format", sb.entity().getFormat(), SearchCriteria.Op.EQ); + sb.and("type", sb.entity().getTemplateType(), SearchCriteria.Op.EQ); + sb.and("bootable", sb.entity().isBootable(), SearchCriteria.Op.EQ); + sb.and("removed", sb.entity().getRemoved(), SearchCriteria.Op.EQ); + + SearchBuilder tagSearch = _tagsDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + sc.setParameters("public", 1); sc.setParameters("format", "ISO"); sc.setParameters("type", TemplateType.PERHOST.toString()); @@ -146,6 +171,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.setParameters("removed", (Object)null); } + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.ISO.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } + return listBy(sc); } @@ -258,7 +293,6 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem PublicIsoSearch.and("type", PublicIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); PublicIsoSearch.and("bootable", PublicIsoSearch.entity().isBootable(), SearchCriteria.Op.EQ); PublicIsoSearch.and("removed", PublicIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); - tmpltTypeHyperSearch = createSearchBuilder(); tmpltTypeHyperSearch.and("templateType", tmpltTypeHyperSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); @@ -314,7 +348,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override public Set> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, - Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller) { + Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, Map tags) { StringBuilder builder = new StringBuilder(); if (!permittedAccounts.isEmpty()) { @@ -431,7 +465,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } @Override - public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr,List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria) { + public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr,List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { StringBuilder builder = new StringBuilder(); if (!permittedAccounts.isEmpty()) { for (Account permittedAccount : permittedAccounts) { @@ -462,6 +496,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem String guestOSJoin = ""; StringBuilder templateHostRefJoin = new StringBuilder(); String dataCenterJoin = "", lpjoin = ""; + String tagsJoin = ""; if (isIso && !hyperType.equals(HypervisorType.None)) { guestOSJoin = " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) "; @@ -474,11 +509,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) { dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } + if (templateFilter == TemplateFilter.sharedexecutable){ lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id "; } + + if (tags != null && !tags.isEmpty()) { + tagsJoin = " INNER JOIN resource_tags r ON t.id = r.resource_id "; + } - sql += guestOSJoin + templateHostRefJoin + dataCenterJoin + lpjoin; + sql += guestOSJoin + templateHostRefJoin + dataCenterJoin + lpjoin + tagsJoin; String whereClause = ""; //All joins have to be made before we start setting the condition settings @@ -491,7 +531,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { whereClause += " AND a.type != " + Account.ACCOUNT_TYPE_PROJECT; } - }else + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { whereClause += " WHERE a.type != " + Account.ACCOUNT_TYPE_PROJECT; } @@ -574,6 +614,19 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && !isIso) { return templateZonePairList; } + + if (tags != null && !tags.isEmpty()) { + whereClause += " AND ("; + boolean first = true; + for (String key : tags.keySet()) { + if (!first) { + whereClause += " OR "; + } + whereClause += "(r.key=\"" + key + "\" and r.value=\"" + tags.get(key) + "\")"; + first = false; + } + whereClause += ")"; + } if (whereClause.equals("")) { whereClause += " WHERE "; @@ -581,7 +634,8 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem whereClause += " AND "; } - sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, bootable, hyperType, zoneId, onlyReady, showDomr) + groupByClause + getOrderByLimit(pageSize, startIndex); + sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, bootable, hyperType, zoneId, + onlyReady, showDomr) + groupByClause + getOrderByLimit(pageSize, startIndex); pstmt = txn.prepareStatement(sql); rs = pstmt.executeQuery(); @@ -594,7 +648,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if(isIso && templateZonePairList.size() < (pageSize != null ? pageSize : 500) && templateFilter != TemplateFilter.community && !(templateFilter == TemplateFilter.self && !BaseCmd.isRootAdmin(caller.getType())) ){ //evaluates to true If root admin and filter=self - List publicIsos = publicIsoSearch(bootable, false); + List publicIsos = publicIsoSearch(bootable, false, tags); for( int i=0; i < publicIsos.size(); i++){ if (keyword != null && publicIsos.get(i).getName().contains(keyword)) { templateZonePairList.add(new Pair(publicIsos.get(i).getId(), null)); diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 6d04d7742e4..f24715c4a37 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -2188,9 +2188,8 @@ CREATE TABLE `cloud`.`resource_tags` ( CONSTRAINT `fk_tags__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), CONSTRAINT `fk_tags__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`), - CONSTRAINT `uc_resource_tags__uuid` UNIQUE (`uuid`), - CONSTRAINT `uc_resource_tags__resource_uuid` UNIQUE (`resource_uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CONSTRAINT `uc_resource_tags__uuid` UNIQUE (`uuid`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`vpc` ( `id` bigint unsigned NOT NULL auto_increment COMMENT 'id',