Completed API / Management server code for Resource tags feature. UI is yet to be done
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/55a12582 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/55a12582 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/55a12582 Branch: refs/heads/master Commit: 55a12582b4630a7bbdae21a1eeeedaf742448cf4 Parents: 62d45b9 Author: Alena Prokharchyk <[email protected]> Authored: Thu Jun 14 15:17:11 2012 -0700 Committer: Alena Prokharchyk <[email protected]> Committed: Wed Jun 20 15:45:08 2012 -0700 ---------------------------------------------------------------------- api/src/com/cloud/api/ApiConstants.java | 1 + api/src/com/cloud/api/commands/CreateTagsCmd.java | 14 +- api/src/com/cloud/api/commands/DeleteTagsCmd.java | 112 +++++++ api/src/com/cloud/api/commands/ListTagsCmd.java | 7 + .../cloud/api/response/ResourceTagResponse.java | 6 + api/src/com/cloud/configuration/Resource.java | 16 - api/src/com/cloud/server/ResourceTag.java | 22 ++- .../com/cloud/server/TaggedResourceService.java | 16 +- server/src/com/cloud/api/ApiDBUtils.java | 2 +- server/src/com/cloud/api/ApiResponseHelper.java | 2 + server/src/com/cloud/tags/ResourceTagVO.java | 19 +- .../com/cloud/tags/TaggedResourceManagerImpl.java | 233 ++++++++++++--- .../cloud/uuididentity/dao/IdentityDaoImpl.java | 38 ++- utils/src/com/cloud/utils/db/DbUtil.java | 5 + utils/src/com/cloud/utils/db/GenericDao.java | 5 + utils/src/com/cloud/utils/db/GenericDaoBase.java | 1 + 16 files changed, 419 insertions(+), 80 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/api/ApiConstants.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 54bfaff..00ec392 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; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/api/commands/CreateTagsCmd.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/api/commands/CreateTagsCmd.java b/api/src/com/cloud/api/commands/CreateTagsCmd.java index c0ac974..5a0b56e 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<String> 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<String> getResourceIds() { return resourceIds; } + + public String getCustomer() { + return customer; + } // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// @@ -101,7 +109,7 @@ public class CreateTagsCmd extends BaseAsyncCmd{ @Override public void execute() { - List<ResourceTag> tags = _taggedResourceService.createTags(getResourceIds(), getResourceType(), getTags()); + List<ResourceTag> tags = _taggedResourceService.createTags(getResourceIds(), getResourceType(), getTags(), getCustomer()); if (tags != null && !tags.isEmpty()) { SuccessResponse response = new SuccessResponse(getCommandName()); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/api/commands/DeleteTagsCmd.java ---------------------------------------------------------------------- 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 0000000..a84a09e --- /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<String> resourceIds; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public TaggedResourceType getResourceType(){ + return _taggedResourceService.getResourceType(resourceType); + } + + public Map<String, String> getTags() { + Map<String, String> tagsMap = null; + if (tag != null && !tag.isEmpty()) { + tagsMap = new HashMap<String, String>(); + Collection<?> servicesCollection = tag.values(); + Iterator<?> iter = servicesCollection.iterator(); + while (iter.hasNext()) { + HashMap<String, String> services = (HashMap<String, String>) iter.next(); + String key = services.get("key"); + String value = services.get("value"); + tagsMap.put(key, value); + } + } + return tagsMap; + } + + public List<String> 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"; + } +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/api/commands/ListTagsCmd.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/api/commands/ListTagsCmd.java b/api/src/com/cloud/api/commands/ListTagsCmd.java index 80e2a2a..8b9eae1 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; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/api/response/ResourceTagResponse.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/api/response/ResourceTagResponse.java b/api/src/com/cloud/api/response/ResourceTagResponse.java index fc8d43c..aa69141 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; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/configuration/Resource.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/configuration/Resource.java b/api/src/com/cloud/configuration/Resource.java index bb2121b..24bb669 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), http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/server/ResourceTag.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 050c8c8..c3307b6 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(); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/api/src/com/cloud/server/TaggedResourceService.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java index 9a4bd32..d76d192 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<ResourceTag> createTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags); + List<ResourceTag> createTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags, String customer); /** * @param resourceId @@ -46,4 +46,12 @@ public interface TaggedResourceService { * @return */ List<? extends ResourceTag> listTags(ListTagsCmd listTagsCmd); + + /** + * @param resourceIds + * @param resourceType + * @param tags + * @return + */ + boolean deleteTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/server/src/com/cloud/api/ApiDBUtils.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index d75ab73..2a0eaaf 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; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/server/src/com/cloud/api/ApiResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index d3c91b8..973a74e 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; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/server/src/com/cloud/tags/ResourceTagVO.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/tags/ResourceTagVO.java b/server/src/com/cloud/tags/ResourceTagVO.java index 74786ba..7aef1e4 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; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/server/src/com/cloud/tags/TaggedResourceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 7e442a9..3d3cf27 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<Resource.TaggedResourceType, String> _resourceMap= - new HashMap<Resource.TaggedResourceType, String>(); - - private static Map<Resource.TaggedResourceType, GenericDao<?, Long>> _daoMap= - new HashMap<Resource.TaggedResourceType, GenericDao<?, Long>>(); + private static Map<TaggedResourceType, GenericDao<?, Long>> _daoMap= + new HashMap<TaggedResourceType, GenericDao<?, Long>>(); @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<String, Object> 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<?, Long> 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; } - - private Pair<Long, Long> 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"); + protected String getTableName(TaggedResourceType resourceType) { + GenericDao<?, Long> dao = _daoMap.get(resourceType); + Class<?> claz = DbUtil.getEntityBeanType(dao); + return DbUtil.getTableName(claz); + } + + private Pair<Long, Long> getAccountDomain(long resourceId, TaggedResourceType resourceType) { + + Pair<Long, Long> pair = null; + GenericDao<?, Long> 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<Long, Long> 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<ResourceTag> createTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags) { + @ActionEvent(eventType = EventTypes.EVENT_TAGS_CREATE, eventDescription = "creating resource tags") + public List<ResourceTag> createTags(List<String> resourceIds, TaggedResourceType resourceType, + Map<String, String> tags, String customer) { Account caller = UserContext.current().getCaller(); List<ResourceTag> resourceTags = new ArrayList<ResourceTag>(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<?, Long> 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<Long, Boolean, ListProjectResourcesCriteria> 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<ResourceTagVO> 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<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags) { + Account caller = UserContext.current().getCaller(); + + SearchBuilder<ResourceTagVO> sb = _resourceTagDao.createSearchBuilder(); + sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN); + sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + SearchCriteria<ResourceTagVO> sc = sb.create(); + sc.setParameters("resourceId", resourceIds.toArray()); + sc.setParameters("resourceType", resourceType); + + List<? extends ResourceTag> resourceTags = _resourceTagDao.search(sc, null);; + List<ResourceTag> tagsToRemove = new ArrayList<ResourceTag>(); + + // 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; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java index 219ed90..a86dbcb 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<IdentityVO, Long> 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<IdentityVO, Long> 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 domain_id FROM `%s` WHERE id=?", tableName)); + pstmt.setLong(1, identityId); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + domainId = rs.getLong(1); + } + } catch (SQLException e) { + } + + //get accountId try { - pstmt = txn.prepareAutoCloseStatement( - String.format("SELECT account_id, domain_id FROM `%s` WHERE id=?", tableName) - ); - + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT account_id FROM `%s` WHERE id=?", tableName)); pstmt.setLong(1, identityId); - ResultSet rs = pstmt.executeQuery(); - if(rs.next()) { - return new Pair<Long, Long>(rs.getLong(1), rs.getLong(2)); - } else { - throw new InvalidParameterValueException("Object " + tableName + "(id: " + identityId + ") does not exist."); + if (rs.next()) { + accountId = rs.getLong(1); } } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); } + return new Pair<Long, Long>(accountId, domainId); } finally { txn.close(); } - return null; } @DB http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/utils/src/com/cloud/utils/db/DbUtil.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/db/DbUtil.java b/utils/src/com/cloud/utils/db/DbUtil.java index dbaa2fa..feef7b3 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<?, Long> dao) { + return dao.getEntityBeanType(); + } + public static boolean releaseGlobalLock(String name) { Connection conn = getConnectionForGlobalLocks(name, false); if(conn == null) { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/utils/src/com/cloud/utils/db/GenericDao.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java index 8fbea61..3ab319e 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<T, ID extends Serializable> { SearchCriteria2 createSearchCriteria2(); public T findOneBy(final SearchCriteria<T> sc); + + /** + * @return + */ + Class<T> getEntityBeanType(); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/55a12582/utils/src/com/cloud/utils/db/GenericDaoBase.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 563232d..938ae15 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<T, ID extends Serializable> implements Gene } @DB(txn=false) + @Override public Class<T> getEntityBeanType() { return _entityBeanType; }
