diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 02cab333f36..97f6b7a95d4 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -67,4 +67,9 @@ public interface ResourceTag extends ControlledEntity{ */ String getCustomer(); + /** + * @return + */ + String getResourceUuid(); + } diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index a1e3b081c73..1948d0c418c 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -293,13 +293,13 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i FirewallRuleVO entry = findById(id); if (entry != null) { if (entry.getPurpose() == Purpose.LoadBalancing) { - _tagsDao.removeBy(id, TaggedResourceType.LoadBalancer); + _tagsDao.removeByIdAndType(id, TaggedResourceType.LoadBalancer); } else if (entry.getPurpose() == Purpose.PortForwarding) { - _tagsDao.removeBy(id, TaggedResourceType.PortForwardingRule); + _tagsDao.removeByIdAndType(id, TaggedResourceType.PortForwardingRule); } else if (entry.getPurpose() == Purpose.Firewall) { - _tagsDao.removeBy(id, TaggedResourceType.FirewallRule); + _tagsDao.removeByIdAndType(id, TaggedResourceType.FirewallRule); } else if (entry.getPurpose() == Purpose.NetworkACL) { - _tagsDao.removeBy(id, TaggedResourceType.NetworkACL); + _tagsDao.removeByIdAndType(id, TaggedResourceType.NetworkACL); } } boolean result = super.remove(id); diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index 42e5f18d459..2ccedcc770a 100755 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -333,7 +333,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen txn.start(); IPAddressVO entry = findById(id); if (entry != null) { - _tagsDao.removeBy(id, TaggedResourceType.SecurityGroup); + _tagsDao.removeByIdAndType(id, TaggedResourceType.SecurityGroup); } boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index d53479fcda3..1c8a82972eb 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -517,7 +517,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N txn.start(); NetworkVO entry = findById(id); if (entry != null) { - _tagsDao.removeBy(id, TaggedResourceType.Network); + _tagsDao.removeByIdAndType(id, TaggedResourceType.Network); } boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java index e16af3d2e92..9334a73e1e1 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java @@ -104,7 +104,7 @@ public class SecurityGroupDaoImpl extends GenericDaoBase txn.start(); SecurityGroupVO entry = findById(id); if (entry != null) { - _tagsDao.removeBy(id, TaggedResourceType.SecurityGroup); + _tagsDao.removeByIdAndType(id, TaggedResourceType.SecurityGroup); } boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java index 9cdca8eeb33..acb97c94198 100644 --- a/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java @@ -105,7 +105,7 @@ public class StaticRouteDaoImpl extends GenericDaoBase impl txn.start(); StaticRouteVO entry = findById(id); if (entry != null) { - _tagsDao.removeBy(id, TaggedResourceType.StaticRoute); + _tagsDao.removeByIdAndType(id, TaggedResourceType.StaticRoute); } boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java index 11f5a2e7d0f..b2d1aab64ea 100644 --- a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java @@ -95,7 +95,7 @@ public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ txn.start(); VpcVO entry = findById(id); if (entry != null) { - _tagsDao.removeBy(id, TaggedResourceType.Vpc); + _tagsDao.removeByIdAndType(id, TaggedResourceType.Vpc); } boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java index 744a54fc933..d7d0d0d95ad 100644 --- a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java +++ b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java @@ -75,7 +75,7 @@ public class ProjectDaoImpl extends GenericDaoBase implements P return false; } - _tagsDao.removeBy(projectId, TaggedResourceType.Project); + _tagsDao.removeByIdAndType(projectId, TaggedResourceType.Project); result = super.remove(projectId); txn.commit(); diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index e13dae2d9a0..1cc774f4970 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -297,7 +297,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements txn.start(); SnapshotVO entry = findById(id); if (entry != null) { - _tagsDao.removeBy(id, TaggedResourceType.Snapshot); + _tagsDao.removeByIdAndType(id, TaggedResourceType.Snapshot); } boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 5a39bd5d16f..9e71f082622 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -799,9 +799,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem template.setRemoved(new Date()); if (template != null) { if (template.getFormat() == ImageFormat.ISO) { - _tagsDao.removeBy(id, TaggedResourceType.ISO); + _tagsDao.removeByIdAndType(id, TaggedResourceType.ISO); } else { - _tagsDao.removeBy(id, TaggedResourceType.Template); + _tagsDao.removeByIdAndType(id, TaggedResourceType.Template); } } diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java index 052a0db482f..48cc5aacf10 100755 --- a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -403,7 +403,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol txn.start(); VolumeVO entry = findById(id); if (entry != null) { - _tagsDao.removeBy(id, TaggedResourceType.Volume); + _tagsDao.removeByIdAndType(id, TaggedResourceType.Volume); } boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/tags/ResourceTagVO.java b/server/src/com/cloud/tags/ResourceTagVO.java index 7aef1e4eaf2..84a9c65083e 100644 --- a/server/src/com/cloud/tags/ResourceTagVO.java +++ b/server/src/com/cloud/tags/ResourceTagVO.java @@ -57,6 +57,9 @@ public class ResourceTagVO implements Identity, ResourceTag{ @Column(name="resource_id") long resourceId; + @Column(name="resource_uuid") + private String resourceUuid; + @Column(name="resource_type") @Enumerated(value=EnumType.STRING) private TaggedResourceType resourceType; @@ -77,9 +80,10 @@ public class ResourceTagVO implements Identity, ResourceTag{ * @param resourceId * @param resourceType * @param customer TODO + * @param resourceUuid TODO */ public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, - TaggedResourceType resourceType, String customer) { + TaggedResourceType resourceType, String customer, String resourceUuid) { super(); this.key = key; this.value = value; @@ -89,6 +93,7 @@ public class ResourceTagVO implements Identity, ResourceTag{ this.resourceType = resourceType; this.uuid = UUID.randomUUID().toString(); this.customer = customer; + this.resourceUuid = resourceUuid; } @@ -145,4 +150,9 @@ public class ResourceTagVO implements Identity, ResourceTag{ public String getCustomer() { return customer; } + + @Override + public String getResourceUuid() { + return resourceUuid; + } } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index f05f422dde6..04f6c94ca46 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -249,10 +249,12 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager for (String tag : tags.keySet()) { for (String resourceId : resourceIds) { Long id = getResourceId(resourceId, resourceType); + String resourceUuid = getUuid(resourceId, resourceType); //check if object exists if (_daoMap.get(resourceType).findById(id) == null) { - throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + + " and type " + resourceType); } Pair accountDomainPair = getAccountDomain(id, resourceType); @@ -270,10 +272,9 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager ResourceTagVO resourceTag = new ResourceTagVO(tag, tags.get(tag), accountDomainPair.first(), accountDomainPair.second(), - id, resourceType, customer); + id, resourceType, customer, resourceUuid); resourceTag = _resourceTagDao.persist(resourceTag); resourceTags.add(resourceTag); - } } @@ -337,7 +338,9 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ); sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ); - sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ); + sb.cp(); sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ); @@ -355,6 +358,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager if (resourceId != null) { sc.setParameters("resourceId", resourceId); + sc.setParameters("resourceUuid", resourceId); } if (resourceType != null) { @@ -375,10 +379,14 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager Account caller = UserContext.current().getCaller(); SearchBuilder sb = _resourceTagDao.createSearchBuilder(); - sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN); + sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN); + sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.IN); + sb.cp(); sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + SearchCriteria sc = sb.create(); sc.setParameters("resourceId", resourceIds.toArray()); + sc.setParameters("resourceUuid", resourceIds.toArray()); sc.setParameters("resourceType", resourceType); List resourceTags = _resourceTagDao.search(sc, null);; @@ -413,6 +421,10 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager } } + if (tagsToRemove.isEmpty()) { + throw new InvalidParameterValueException("Unable to find tags by parameters specified"); + } + //Remove the tags Transaction txn = Transaction.currentTxn(); txn.start(); diff --git a/server/src/com/cloud/tags/dao/ResourceTagDao.java b/server/src/com/cloud/tags/dao/ResourceTagDao.java index 07e359b2978..9f617fb104e 100644 --- a/server/src/com/cloud/tags/dao/ResourceTagDao.java +++ b/server/src/com/cloud/tags/dao/ResourceTagDao.java @@ -29,8 +29,15 @@ public interface ResourceTagDao extends GenericDao{ * @param resourceType * @return */ - boolean removeBy(long resourceId, TaggedResourceType resourceType); + boolean removeByIdAndType(long resourceId, TaggedResourceType resourceType); List listBy(long resourceId, TaggedResourceType resourceType); +// /** +// * @param resourceUuId +// * @param resourceType +// * @return +// */ +// ResourceTag findByUuid(String resourceUuId, TaggedResourceType resourceType); + } diff --git a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java index 84ce1e02983..3a84e921753 100644 --- a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java +++ b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java @@ -35,18 +35,27 @@ public class ResourceTagsDaoImpl extends GenericDaoBase imp protected ResourceTagsDaoImpl() { AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("resourceId", AllFieldsSearch.entity().getResourceId(), Op.EQ); + AllFieldsSearch.and("uuid", AllFieldsSearch.entity().getResourceUuid(), Op.EQ); AllFieldsSearch.and("resourceType", AllFieldsSearch.entity().getResourceType(), Op.EQ); AllFieldsSearch.done(); } @Override - public boolean removeBy(long resourceId, ResourceTag.TaggedResourceType resourceType) { + public boolean removeByIdAndType(long resourceId, ResourceTag.TaggedResourceType resourceType) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("resourceId", resourceId); sc.setParameters("resourceType", resourceType); remove(sc); return true; } + +// @Override +// public ResourceTag findByUuid(String resourceUuId, ResourceTag.TaggedResourceType resourceType) { +// SearchCriteria sc = AllFieldsSearch.create(); +// sc.setParameters("uuid", resourceUuId); +// sc.setParameters("resourceType", resourceType); +// return findOneBy(sc); +// } @Override public List listBy(long resourceId, TaggedResourceType resourceType) { diff --git a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java b/server/src/com/cloud/vm/dao/UserVmDaoImpl.java index 6e2b05fdacd..34b2eac401b 100755 --- a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/server/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -549,7 +549,7 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use public boolean remove(Long id) { Transaction txn = Transaction.currentTxn(); txn.start(); - _tagsDao.removeBy(id, TaggedResourceType.UserVm); + _tagsDao.removeByIdAndType(id, TaggedResourceType.UserVm); boolean result = super.remove(id); txn.commit(); return result; diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 03939ee2b4f..51e80fd65c1 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -557,7 +557,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem txn.start(); VMInstanceVO vm = findById(id); if (vm != null && vm.getType() == Type.User) { - _tagsDao.removeBy(id, TaggedResourceType.UserVm); + _tagsDao.removeByIdAndType(id, TaggedResourceType.UserVm); } boolean result = super.remove(id); txn.commit(); diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index b33459ad2f4..5e6fe5db500 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -2179,6 +2179,7 @@ CREATE TABLE `cloud`.`resource_tags` ( `key` varchar(255), `value` varchar(255), `resource_id` bigint unsigned NOT NULL, + `resource_uuid` varchar(40), `resource_type` varchar(255), `customer` varchar(255), `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', @@ -2186,7 +2187,9 @@ CREATE TABLE `cloud`.`resource_tags` ( PRIMARY KEY (`id`), 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`) + 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; CREATE TABLE `cloud`.`vpc` (