diff --git a/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagDao.java b/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagDao.java index 034ea61ee0e..5efaea40a94 100644 --- a/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagDao.java +++ b/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagDao.java @@ -63,8 +63,12 @@ public interface ResourceTagDao extends GenericDao { List listByResourceUuid(String resourceUuid); - List listByResourceTypeKeyAndOwners(ResourceObjectType resourceType, String key, - List accountIds, List domainIds, Filter filter); + List listByResourceTypeKeyPrefixAndOwners(ResourceObjectType resourceType, String key, + List accountIds, List domainIds, + Filter filter); + + ResourceTagVO findByResourceTypeKeyPrefixAndValue(ResourceObjectType resourceType, String key, String value); + + List listByResourceTypeIdAndKeyPrefix(ResourceObjectType resourceType, long resourceId, String key); - ResourceTagVO findByResourceTypeKeyAndValue(ResourceObjectType resourceType, String key, String value); } diff --git a/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagsDaoImpl.java index b82dd5ec3de..22c7b7b2ee5 100644 --- a/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagsDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagsDaoImpl.java @@ -31,6 +31,7 @@ import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; @@ -124,12 +125,13 @@ public class ResourceTagsDaoImpl extends GenericDaoBase imp } @Override - public List listByResourceTypeKeyAndOwners(ResourceObjectType resourceType, String key, - List accountIds, List domainIds, - Filter filter) { - SearchBuilder sb = createSearchBuilder(); + public List listByResourceTypeKeyPrefixAndOwners(ResourceObjectType resourceType, String key, + List accountIds, List domainIds, + Filter filter) { + GenericSearchBuilder sb = createSearchBuilder(String.class); + sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getValue()); sb.and("resourceType", sb.entity().getResourceType(), Op.EQ); - sb.and("key", sb.entity().getKey(), Op.EQ); + sb.and("key", sb.entity().getKey(), Op.LIKE); boolean accountIdsNotEmpty = CollectionUtils.isNotEmpty(accountIds); boolean domainIdsNotEmpty = CollectionUtils.isNotEmpty(domainIds); if (accountIdsNotEmpty || domainIdsNotEmpty) { @@ -138,30 +140,45 @@ public class ResourceTagsDaoImpl extends GenericDaoBase imp sb.cp(); } sb.done(); - final SearchCriteria sc = sb.create(); + final SearchCriteria sc = sb.create(); sc.setParameters("resourceType", resourceType); - sc.setParameters("key", key); + sc.setParameters("key", key + "%"); if (accountIdsNotEmpty) { sc.setParameters("account", accountIds.toArray()); } if (domainIdsNotEmpty) { sc.setParameters("domain", domainIds.toArray()); } - return listBy(sc, filter); + return customSearch(sc, filter); } @Override - public ResourceTagVO findByResourceTypeKeyAndValue(ResourceObjectType resourceType, String key, + public ResourceTagVO findByResourceTypeKeyPrefixAndValue(ResourceObjectType resourceType, String key, String value) { SearchBuilder sb = createSearchBuilder(); sb.and("resourceType", sb.entity().getResourceType(), Op.EQ); - sb.and("key", sb.entity().getKey(), Op.EQ); + sb.and("key", sb.entity().getKey(), Op.LIKE); sb.and("value", sb.entity().getValue(), Op.EQ); sb.done(); final SearchCriteria sc = sb.create(); sc.setParameters("resourceType", resourceType); - sc.setParameters("key", key); + sc.setParameters("key", key + "%"); sc.setParameters("value", value); return findOneBy(sc); } + + @Override + public List listByResourceTypeIdAndKeyPrefix(ResourceObjectType resourceType, long resourceId, + String key) { + SearchBuilder sb = createSearchBuilder(); + sb.and("resourceType", sb.entity().getResourceType(), Op.EQ); + sb.and("resourceId", sb.entity().getResourceId(), Op.EQ); + sb.and("key", sb.entity().getKey(), Op.LIKE); + sb.done(); + final SearchCriteria sc = sb.create(); + sc.setParameters("resourceType", resourceType); + sc.setParameters("resourceId", resourceId); + sc.setParameters("key", key + "%"); + return listBy(sc); + } } diff --git a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/adapter/ServerAdapter.java b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/adapter/ServerAdapter.java index 3990b1e129a..4b07f32ee03 100644 --- a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/adapter/ServerAdapter.java +++ b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/adapter/ServerAdapter.java @@ -1186,14 +1186,8 @@ public class ServerAdapter extends ManagerBase { @ApiAccess(command = ListTagsCmd.class) protected List listTagsByInstanceId(final long instanceId) { - ResourceTag vmResourceTag = resourceTagDao.findByKey(instanceId, - ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY); - List tags = new ArrayList<>(); - if (vmResourceTag instanceof ResourceTagVO) { - tags.add((ResourceTagVO)vmResourceTag); - } else { - tags.add(resourceTagDao.findById(vmResourceTag.getId())); - } + List tags = resourceTagDao.listByResourceTypeIdAndKeyPrefix( + ResourceTag.ResourceObjectType.UserVm, instanceId, VM_TA_KEY); return ResourceTagVOToTagConverter.toTags(tags); } @@ -1759,10 +1753,10 @@ public class ServerAdapter extends ManagerBase { List tags = new ArrayList<>(getDummyTags().values()); Filter filter = new Filter(ResourceTagVO.class, "id", true, offset, limit); Pair, List> ownerDetails = getResourceOwnerFiltersWithDomainIds(); - List vmResourceTags = resourceTagDao.listByResourceTypeKeyAndOwners( + List vmResourceTags = resourceTagDao.listByResourceTypeKeyPrefixAndOwners( ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY, ownerDetails.first(), ownerDetails.second(), filter); if (CollectionUtils.isNotEmpty(vmResourceTags)) { - tags.addAll(ResourceTagVOToTagConverter.toTags(vmResourceTags)); + tags.addAll(ResourceTagVOToTagConverter.toTagsFromValues(vmResourceTags)); } return tags; } @@ -1774,7 +1768,7 @@ public class ServerAdapter extends ManagerBase { } Tag tag = getDummyTags().get(uuid); if (tag == null) { - ResourceTagVO resourceTagVO = resourceTagDao.findByResourceTypeKeyAndValue( + ResourceTagVO resourceTagVO = resourceTagDao.findByResourceTypeKeyPrefixAndValue( ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY, uuid); accountService.checkAccess(CallContext.current().getCallingAccount(), null, false, resourceTagVO); diff --git a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ResourceTagVOToTagConverter.java b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ResourceTagVOToTagConverter.java index 9715b032110..38d67a77837 100644 --- a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ResourceTagVOToTagConverter.java +++ b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ResourceTagVOToTagConverter.java @@ -61,7 +61,22 @@ public class ResourceTagVOToTagConverter { return tag; } + public static Tag toTag(String id) { + String basePath = VeeamControlService.ContextPath.value(); + Tag tag = new Tag(); + tag.setId(id); + tag.setName(id); + tag.setDescription(String.format("Tag: %s", id)); + tag.setHref(basePath + TagsRouteHandler.BASE_ROUTE + "/" + id); + tag.setParent(getRootTagRef()); + return tag; + } + public static List toTags(List vos) { return vos.stream().map(ResourceTagVOToTagConverter::toTag).collect(Collectors.toList()); } + + public static List toTagsFromValues(List values) { + return values.stream().map(ResourceTagVOToTagConverter::toTag).collect(Collectors.toList()); + } }