diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 54bfaff8883..00ec392d7b9 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -360,6 +360,7 @@ public class ApiConstants { public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy"; public static final String RESOURCE_IDS = "resourceids"; public static final String RESOURCE_ID = "resourceid"; + public static final String CUSTOMER = "customer"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/com/cloud/api/commands/CreateTagsCmd.java b/api/src/com/cloud/api/commands/CreateTagsCmd.java index c0ac9742a26..5a0b56e544e 100644 --- a/api/src/com/cloud/api/commands/CreateTagsCmd.java +++ b/api/src/com/cloud/api/commands/CreateTagsCmd.java @@ -27,9 +27,9 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; -import com.cloud.configuration.Resource; import com.cloud.event.EventTypes; import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; /** * @author Alena Prokharchyk @@ -54,13 +54,17 @@ public class CreateTagsCmd extends BaseAsyncCmd{ @Parameter(name=ApiConstants.RESOURCE_IDS, type=CommandType.LIST, required=true, collectionType=CommandType.STRING, description="list of resources to create the tags for") private List resourceIds; + + @Parameter(name=ApiConstants.CUSTOMER, type=CommandType.STRING, description="identifies client specific tag. " + + "When the value is not null, the tag can't be used by cloudStack code internally") + private String customer; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public Resource.TaggedResourceType getResourceType(){ + public TaggedResourceType getResourceType(){ return _taggedResourceService.getResourceType(resourceType); } @@ -83,6 +87,10 @@ public class CreateTagsCmd extends BaseAsyncCmd{ public List getResourceIds() { return resourceIds; } + + public String getCustomer() { + return customer; + } // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// @@ -101,7 +109,7 @@ public class CreateTagsCmd extends BaseAsyncCmd{ @Override public void execute() { - List tags = _taggedResourceService.createTags(getResourceIds(), getResourceType(), getTags()); + List tags = _taggedResourceService.createTags(getResourceIds(), getResourceType(), getTags(), getCustomer()); if (tags != null && !tags.isEmpty()) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/com/cloud/api/commands/DeleteTagsCmd.java b/api/src/com/cloud/api/commands/DeleteTagsCmd.java new file mode 100644 index 00000000000..a84a09ec38b --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteTagsCmd.java @@ -0,0 +1,112 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +package com.cloud.api.commands; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description = "Deleting resource tag(s)", responseObject = SuccessResponse.class, since = "Burbank") +public class DeleteTagsCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteTagsCmd.class.getName()); + + private static final String s_name = "deleteTagsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, description = "Delete tags matching key/value pairs") + private Map tag; + + @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, required=true, description="Delete tag by resource type") + private String resourceType; + + @Parameter(name=ApiConstants.RESOURCE_IDS, type=CommandType.LIST, required=true, + collectionType=CommandType.STRING, description="Delete tags for resource id(s)") + private List resourceIds; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public TaggedResourceType getResourceType(){ + return _taggedResourceService.getResourceType(resourceType); + } + + public Map getTags() { + Map tagsMap = null; + if (tag != null && !tag.isEmpty()) { + tagsMap = new HashMap(); + Collection servicesCollection = tag.values(); + Iterator iter = servicesCollection.iterator(); + while (iter.hasNext()) { + HashMap services = (HashMap) iter.next(); + String key = services.get("key"); + String value = services.get("value"); + tagsMap.put(key, value); + } + } + return tagsMap; + } + + public List getResourceIds() { + return resourceIds; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + //FIXME - validate the owner here + return 1; + } + + @Override + public void execute() { + boolean success = _taggedResourceService.deleteTags(getResourceIds(), getResourceType(), getTags()); + + if (success) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete tags"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_TAGS_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting tags"; + } +} diff --git a/api/src/com/cloud/api/commands/ListTagsCmd.java b/api/src/com/cloud/api/commands/ListTagsCmd.java index 80e2a2a9fde..8b9eae195ed 100644 --- a/api/src/com/cloud/api/commands/ListTagsCmd.java +++ b/api/src/com/cloud/api/commands/ListTagsCmd.java @@ -43,6 +43,9 @@ public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd{ @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, description="list by value") private String value; + @Parameter(name=ApiConstants.CUSTOMER, type=CommandType.STRING, description="list by customer name") + private String customer; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -84,4 +87,8 @@ public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd{ public String getCommandName() { return s_name; } + + public String getCustomer() { + return customer; + } } diff --git a/api/src/com/cloud/api/response/ResourceTagResponse.java b/api/src/com/cloud/api/response/ResourceTagResponse.java index fc8d43c7b60..aa69141113e 100644 --- a/api/src/com/cloud/api/response/ResourceTagResponse.java +++ b/api/src/com/cloud/api/response/ResourceTagResponse.java @@ -52,6 +52,9 @@ public class ResourceTagResponse extends BaseResponse implements ControlledEntit @SerializedName(ApiConstants.DOMAIN) @Param(description = "the domain associated with the tag") private String domainName; + + @SerializedName(ApiConstants.CUSTOMER) @Param(description="customer associated with the tag") + private String customer; public void setKey(String key) { this.key = key; @@ -91,4 +94,7 @@ public class ResourceTagResponse extends BaseResponse implements ControlledEntit this.projectName = projectName; } + public void setCustomer(String customer) { + this.customer = customer; + } } diff --git a/api/src/com/cloud/configuration/Resource.java b/api/src/com/cloud/configuration/Resource.java index bb2121b1cfd..24bb669c4e2 100644 --- a/api/src/com/cloud/configuration/Resource.java +++ b/api/src/com/cloud/configuration/Resource.java @@ -19,22 +19,6 @@ package com.cloud.configuration; public interface Resource { public static final short RESOURCE_UNLIMITED = -1; - - public enum TaggedResourceType { - UserVm, - Template, - ISO, - Volume, - Snapshot, - Network, - LoadBalancingRule, - PortForwardingRule, - FirewallRule, - SecurityGroup, - RemoteAccessVpn, - PublicIpAdddress, - SecondaryStorageVm - } public enum ResourceType { user_vm("user_vm", 0, ResourceOwnerType.Account, ResourceOwnerType.Domain), diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 050c8c8b94b..c3307b6b17b 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -13,12 +13,25 @@ package com.cloud.server; import com.cloud.acl.ControlledEntity; -import com.cloud.configuration.Resource; /** * @author Alena Prokharchyk */ public interface ResourceTag extends ControlledEntity{ + + public enum TaggedResourceType { + UserVm, + Template, + ISO, + Volume, + Snapshot, + Network, + LoadBalancer, + PortForwardingRule, + FirewallRule, + SecurityGroup, + PublicIpAddress + } /** * @return @@ -43,6 +56,11 @@ public interface ResourceTag extends ControlledEntity{ /** * @return */ - Resource.TaggedResourceType getResourceType(); + TaggedResourceType getResourceType(); + + /** + * @return + */ + String getCustomer(); } diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java index 9a4bd326b4b..d76d19265df 100644 --- a/api/src/com/cloud/server/TaggedResourceService.java +++ b/api/src/com/cloud/server/TaggedResourceService.java @@ -16,23 +16,23 @@ import java.util.List; import java.util.Map; import com.cloud.api.commands.ListTagsCmd; -import com.cloud.configuration.Resource; -import com.cloud.configuration.Resource.TaggedResourceType; +import com.cloud.server.ResourceTag.TaggedResourceType; /** * @author Alena Prokharchyk */ public interface TaggedResourceService { - Resource.TaggedResourceType getResourceType (String resourceTypeStr); + TaggedResourceType getResourceType (String resourceTypeStr); /** * @param resourceIds TODO * @param resourceType * @param tags + * @param customer TODO * @return */ - List createTags(List resourceIds, TaggedResourceType resourceType, Map tags); + List createTags(List resourceIds, TaggedResourceType resourceType, Map tags, String customer); /** * @param resourceId @@ -46,4 +46,12 @@ public interface TaggedResourceService { * @return */ List listTags(ListTagsCmd listTagsCmd); + + /** + * @param resourceIds + * @param resourceType + * @param tags + * @return + */ + boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags); } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index d75ab7315e2..2a0eaaf22d5 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -25,7 +25,6 @@ import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationService; import com.cloud.configuration.Resource.ResourceType; -import com.cloud.configuration.Resource.TaggedResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterVO; @@ -78,6 +77,7 @@ import com.cloud.projects.ProjectService; import com.cloud.resource.ResourceManager; import com.cloud.server.Criteria; import com.cloud.server.ManagementServer; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.StatsCollector; import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index d3c91b8c7e2..973a74efd88 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3430,6 +3430,8 @@ public class ApiResponseHelper implements ResponseGenerator { response.setDomainName(ApiDBUtils.findDomainById(domainId).getName()); } + response.setCustomer(resourceTag.getCustomer()); + response.setObjectName("tag"); return response; diff --git a/server/src/com/cloud/tags/ResourceTagVO.java b/server/src/com/cloud/tags/ResourceTagVO.java index 74786ba2d9f..7aef1e4eaf2 100644 --- a/server/src/com/cloud/tags/ResourceTagVO.java +++ b/server/src/com/cloud/tags/ResourceTagVO.java @@ -24,8 +24,6 @@ import javax.persistence.Id; import javax.persistence.Table; import com.cloud.api.Identity; -import com.cloud.configuration.Resource; -import com.cloud.configuration.Resource.TaggedResourceType; import com.cloud.server.ResourceTag; /** @@ -61,7 +59,10 @@ public class ResourceTagVO implements Identity, ResourceTag{ @Column(name="resource_type") @Enumerated(value=EnumType.STRING) - private Resource.TaggedResourceType resourceType; + private TaggedResourceType resourceType; + + @Column(name="customer") + String customer; protected ResourceTagVO(){ @@ -75,8 +76,10 @@ public class ResourceTagVO implements Identity, ResourceTag{ * @param domainId * @param resourceId * @param resourceType + * @param customer TODO */ - public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, TaggedResourceType resourceType) { + public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, + TaggedResourceType resourceType, String customer) { super(); this.key = key; this.value = value; @@ -85,6 +88,7 @@ public class ResourceTagVO implements Identity, ResourceTag{ this.resourceId = resourceId; this.resourceType = resourceType; this.uuid = UUID.randomUUID().toString(); + this.customer = customer; } @@ -128,7 +132,7 @@ public class ResourceTagVO implements Identity, ResourceTag{ } @Override - public Resource.TaggedResourceType getResourceType() { + public TaggedResourceType getResourceType() { return resourceType; } @@ -136,4 +140,9 @@ public class ResourceTagVO implements Identity, ResourceTag{ public String getUuid() { return uuid; } + + @Override + public String getCustomer() { + return customer; + } } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 7e442a91fcf..3d3cf27d405 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -23,14 +23,25 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.api.commands.ListTagsCmd; -import com.cloud.configuration.Resource; -import com.cloud.configuration.Resource.TaggedResourceType; import com.cloud.domain.Domain; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.RemoteAccessVpnDao; +import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.TaggedResourceService; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -48,7 +59,6 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.uuididentity.dao.IdentityDao; -import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.UserVmDao; /** @@ -59,11 +69,8 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class); private String _name; - private static Map _resourceMap= - new HashMap(); - - private static Map> _daoMap= - new HashMap>(); + private static Map> _daoMap= + new HashMap>(); @Inject AccountManager _accountMgr; @@ -75,15 +82,42 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager DomainManager _domainMgr; @Inject UserVmDao _userVmDao; + @Inject + VolumeDao _volumeDao; + @Inject + VMTemplateDao _templateDao; + @Inject + SnapshotDao _snapshotDao; + @Inject + NetworkDao _networkDao; + @Inject + LoadBalancerDao _lbDao; + @Inject + PortForwardingRulesDao _pfDao; + @Inject + FirewallRulesDao _firewallDao; + @Inject + SecurityGroupDao _securityGroupDao; + @Inject + RemoteAccessVpnDao _vpnDao; + @Inject + IPAddressDao _publicIpDao; - @Override public boolean configure(String name, Map params) throws ConfigurationException { _name = name; - _resourceMap.put(TaggedResourceType.UserVm, DbUtil.getTableName(VMInstanceVO.class)); _daoMap.put(TaggedResourceType.UserVm, _userVmDao); - - + _daoMap.put(TaggedResourceType.Volume, _volumeDao); + _daoMap.put(TaggedResourceType.Template, _templateDao); + _daoMap.put(TaggedResourceType.ISO, _templateDao); + _daoMap.put(TaggedResourceType.Snapshot, _snapshotDao); + _daoMap.put(TaggedResourceType.Network, _networkDao); + _daoMap.put(TaggedResourceType.LoadBalancer, _lbDao); + _daoMap.put(TaggedResourceType.PortForwardingRule, _pfDao); + _daoMap.put(TaggedResourceType.FirewallRule, _firewallDao); + _daoMap.put(TaggedResourceType.SecurityGroup, _securityGroupDao); + _daoMap.put(TaggedResourceType.PublicIpAddress, _publicIpDao); + return true; } @@ -103,24 +137,61 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager } - private Long getResourceId(String resourceId, Resource.TaggedResourceType resourceType) { - String tableName = _resourceMap.get(resourceType); - - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); - } + private Long getResourceId(String resourceId, TaggedResourceType resourceType) { + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); - return _identityDao.getIdentityId(tableName, resourceId); + Long identityId = null; + + while (claz != null && claz != Object.class) { + try { + String tableName = DbUtil.getTableName(claz); + if (tableName == null) { + throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); + } + identityId = _identityDao.getIdentityId(tableName, resourceId); + if (identityId != null) { + break; + } + } catch (Exception ex) { + //do nothing here, it might mean uuid field is missing and we have to search further + } + claz = claz.getSuperclass(); + } + + if (identityId == null) { + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); + } + return identityId; + } + + protected String getTableName(TaggedResourceType resourceType) { + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); + return DbUtil.getTableName(claz); } - private Pair getAccountDomain(long resourceId, Resource.TaggedResourceType resourceType) { - String tableName = _resourceMap.get(resourceType); - - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); + private Pair getAccountDomain(long resourceId, TaggedResourceType resourceType) { + + Pair pair = null; + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); + while (claz != null && claz != Object.class) { + try { + String tableName = DbUtil.getTableName(claz); + if (tableName == null) { + throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); + } + pair = _identityDao.getAccountDomainInfo(tableName, resourceId); + if (pair.first() != null || pair.second() != null) { + break; + } + } catch (Exception ex) { + //do nothing here, it might mean uuid field is missing and we have to search further + } + claz = claz.getSuperclass(); } - - Pair pair = _identityDao.getAccountDomainInfo(tableName, resourceId); + Long accountId = pair.first(); Long domainId = pair.second(); @@ -137,19 +208,20 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager @Override public TaggedResourceType getResourceType(String resourceTypeStr) { - Resource.TaggedResourceType resourceType = null; - try { - resourceType = Resource.TaggedResourceType.valueOf(resourceTypeStr); - } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException("Invalid resource type " + resourceType); - } - return resourceType; + for (TaggedResourceType type : ResourceTag.TaggedResourceType.values()) { + if (type.toString().equalsIgnoreCase(resourceTypeStr)) { + return type; + } + } + throw new InvalidParameterValueException("Invalid resource type " + resourceTypeStr); } @Override @DB - public List createTags(List resourceIds, TaggedResourceType resourceType, Map tags) { + @ActionEvent(eventType = EventTypes.EVENT_TAGS_CREATE, eventDescription = "creating resource tags") + public List createTags(List resourceIds, TaggedResourceType resourceType, + Map tags, String customer) { Account caller = UserContext.current().getCaller(); List resourceTags = new ArrayList(tags.size()); @@ -181,7 +253,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager ResourceTagVO resourceTag = new ResourceTagVO(tag, tags.get(tag), accountDomainPair.first(), accountDomainPair.second(), - id, resourceType); + id, resourceType, customer); resourceTag = _resourceTagDao.persist(resourceTag); resourceTags.add(resourceTag); @@ -195,7 +267,32 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager @Override public String getUuid(String resourceId, TaggedResourceType resourceType) { - return _identityDao.getIdentityUuid(_resourceMap.get(resourceType), resourceId); + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); + + String identiyUUId = null; + + while (claz != null && claz != Object.class) { + try { + String tableName = DbUtil.getTableName(claz); + if (tableName == null) { + throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); + } + identiyUUId = _identityDao.getIdentityUuid(tableName, resourceId); + if (identiyUUId != null) { + break; + } + } catch (Exception ex) { + //do nothing here, it might mean uuid field is missing and we have to search further + } + claz = claz.getSuperclass(); + } + + if (identiyUUId == null) { + return resourceId; + } + + return identiyUUId; } @Override @@ -206,6 +303,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager String value = cmd.getValue(); String resourceId = cmd.getResourceId(); String resourceType = cmd.getResourceType(); + String customerName = cmd.getCustomer(); boolean listAll = cmd.listAll(); Ternary domainIdRecursiveListProject = @@ -224,6 +322,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ); sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ); // now set the SC criteria... SearchCriteria sc = sb.create(); @@ -245,7 +344,67 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager sc.setParameters("resourceType", resourceType); } + if (customerName != null) { + sc.setParameters("customer", customerName); + } + return _resourceTagDao.search(sc, searchFilter); } + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_TAGS_DELETE, eventDescription = "deleting resource tags") + public boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags) { + Account caller = UserContext.current().getCaller(); + + SearchBuilder sb = _resourceTagDao.createSearchBuilder(); + sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN); + sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + SearchCriteria sc = sb.create(); + sc.setParameters("resourceId", resourceIds.toArray()); + sc.setParameters("resourceType", resourceType); + + List resourceTags = _resourceTagDao.search(sc, null);; + List tagsToRemove = new ArrayList(); + + // Finalize which tags should be removed + for (ResourceTag resourceTag : resourceTags) { + //1) validate the permissions + Account owner = _accountMgr.getAccount(resourceTag.getAccountId()); + _accountMgr.checkAccess(caller, null, false, owner); + //2) Only remove tag if it matches key value pairs + if (tags != null && !tags.isEmpty()) { + for (String key : tags.keySet()) { + boolean canBeRemoved = false; + if (resourceTag.getKey().equalsIgnoreCase(key)) { + String value = tags.get(key); + if (value != null) { + if (resourceTag.getValue().equalsIgnoreCase(value)) { + canBeRemoved = true; + } + } else { + canBeRemoved = true; + } + if (canBeRemoved) { + tagsToRemove.add(resourceTag); + break; + } + } + } + } else { + tagsToRemove.add(resourceTag); + } + } + + //Remove the tags + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (ResourceTag tagToRemove : tagsToRemove) { + _resourceTagDao.remove(tagToRemove.getId()); + s_logger.debug("Removed the tag " + tagToRemove); + } + txn.commit(); + + return true; + } } diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java index 219ed90e28b..a86dbcb0447 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java +++ b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java @@ -51,7 +51,14 @@ public class IdentityDaoImpl extends GenericDaoBase implements PreparedStatement pstmt = null; Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { - try { + try { + try { + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT uuid FROM `%s`", tableName)); + pstmt.executeQuery(); + } catch (SQLException e) { + throw new InvalidParameterValueException("uuid field doesn't exist in table " + tableName); + } + pstmt = txn.prepareAutoCloseStatement( String.format("SELECT id FROM `%s` WHERE id=? OR uuid=?", tableName) @@ -96,26 +103,33 @@ public class IdentityDaoImpl extends GenericDaoBase implements PreparedStatement pstmt = null; Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { + Long domainId = null; + Long accountId = null; + //get domainId try { - pstmt = txn.prepareAutoCloseStatement( - String.format("SELECT account_id, domain_id FROM `%s` WHERE id=?", tableName) - ); - + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT domain_id FROM `%s` WHERE id=?", tableName)); pstmt.setLong(1, identityId); - ResultSet rs = pstmt.executeQuery(); - if(rs.next()) { - return new Pair(rs.getLong(1), rs.getLong(2)); - } else { - throw new InvalidParameterValueException("Object " + tableName + "(id: " + identityId + ") does not exist."); + if (rs.next()) { + domainId = rs.getLong(1); } } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); } + + //get accountId + try { + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT account_id FROM `%s` WHERE id=?", tableName)); + pstmt.setLong(1, identityId); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + accountId = rs.getLong(1); + } + } catch (SQLException e) { + } + return new Pair(accountId, domainId); } finally { txn.close(); } - return null; } @DB diff --git a/utils/src/com/cloud/utils/db/DbUtil.java b/utils/src/com/cloud/utils/db/DbUtil.java index dbaa2fa9b7f..feef7b3b236 100755 --- a/utils/src/com/cloud/utils/db/DbUtil.java +++ b/utils/src/com/cloud/utils/db/DbUtil.java @@ -244,6 +244,11 @@ public class DbUtil { return false; } + + public static Class getEntityBeanType(GenericDao dao) { + return dao.getEntityBeanType(); + } + public static boolean releaseGlobalLock(String name) { Connection conn = getConnectionForGlobalLocks(name, false); if(conn == null) { diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java index 8fbea61df8e..3ab319ea830 100755 --- a/utils/src/com/cloud/utils/db/GenericDao.java +++ b/utils/src/com/cloud/utils/db/GenericDao.java @@ -255,4 +255,9 @@ public interface GenericDao { SearchCriteria2 createSearchCriteria2(); public T findOneBy(final SearchCriteria sc); + + /** + * @return + */ + Class getEntityBeanType(); } diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 563232d6121..938ae15717e 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -840,6 +840,7 @@ public abstract class GenericDaoBase implements Gene } @DB(txn=false) + @Override public Class getEntityBeanType() { return _entityBeanType; }