From 1011dfd31c1c02e84ca20fca6d139f0bc3f9334a Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Tue, 3 Jul 2012 14:43:52 -0700 Subject: [PATCH] Resource tags: 1) Remove tag records when correspdonding cloudStack object gets removed 2) added "tags" request parameter to the banch of list* Api commands (listVirtualMachines, listSnapshots - all commands are listed in the resource tags functional spec) --- .../cloud/api/BaseListDomainResourcesCmd.java | 9 +- ...BaseListProjectAndAccountResourcesCmd.java | 2 +- .../cloud/api/BaseListTaggedResourcesCmd.java | 47 +++++ api/src/com/cloud/api/ResponseGenerator.java | 3 +- .../api/commands/ListFirewallRulesCmd.java | 4 +- .../com/cloud/api/commands/ListIsosCmd.java | 4 +- .../commands/ListLoadBalancerRulesCmd.java | 5 +- .../cloud/api/commands/ListNetworksCmd.java | 4 +- .../commands/ListPortForwardingRulesCmd.java | 4 +- .../commands/ListPublicIpAddressesCmd.java | 4 +- .../api/commands/ListSecurityGroupsCmd.java | 5 +- .../cloud/api/commands/ListSnapshotsCmd.java | 4 +- .../com/cloud/api/commands/ListTagsCmd.java | 2 +- .../cloud/api/commands/ListTemplatesCmd.java | 5 +- .../com/cloud/api/commands/ListVMsCmd.java | 4 +- .../cloud/api/commands/ListVolumesCmd.java | 4 +- .../cloud/api/response/FirewallResponse.java | 9 + .../api/response/FirewallRuleResponse.java | 11 +- .../cloud/api/response/IPAddressResponse.java | 10 +- .../api/response/LoadBalancerResponse.java | 11 +- .../cloud/api/response/NetworkResponse.java | 7 + .../api/response/SecurityGroupResponse.java | 9 +- .../cloud/api/response/SnapshotResponse.java | 10 +- .../cloud/api/response/TemplateResponse.java | 8 + .../cloud/api/response/UserVmResponse.java | 9 +- .../cloud/api/response/VolumeResponse.java | 10 +- .../cloud/server/TaggedResourceService.java | 2 + server/src/com/cloud/api/ApiDBUtils.java | 13 +- .../src/com/cloud/api/ApiResponseHelper.java | 169 +++++++++++++++--- .../com/cloud/netapp/dao/VolumeDaoImpl.java | 1 + .../com/cloud/network/NetworkManagerImpl.java | 38 +++- .../network/dao/FirewallRulesDaoImpl.java | 25 ++- .../cloud/network/dao/IPAddressDaoImpl.java | 17 ++ .../network/dao/LoadBalancerDaoImpl.java | 2 +- .../com/cloud/network/dao/NetworkDaoImpl.java | 17 +- .../network/firewall/FirewallManagerImpl.java | 30 ++++ .../lb/LoadBalancingRulesManagerImpl.java | 29 +++ .../cloud/network/rules/RulesManagerImpl.java | 30 +++- .../security/SecurityGroupManagerImpl.java | 29 +++ .../security/dao/SecurityGroupDaoImpl.java | 28 ++- .../cloud/server/ManagementServerImpl.java | 49 ++++- .../com/cloud/storage/StorageManagerImpl.java | 28 +++ .../cloud/storage/dao/SnapshotDaoImpl.java | 19 +- .../cloud/storage/dao/VMTemplateDaoImpl.java | 22 ++- .../com/cloud/storage/dao/VolumeDaoImpl.java | 18 ++ .../storage/snapshot/SnapshotManagerImpl.java | 30 ++++ .../cloud/tags/TaggedResourceManagerImpl.java | 6 + .../com/cloud/tags/dao/ResourceTagDao.java | 13 ++ .../cloud/tags/dao/ResourceTagsDaoImpl.java | 31 +++- server/src/com/cloud/vm/UserVmManager.java | 3 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 34 +++- server/src/com/cloud/vm/dao/UserVmDao.java | 1 + .../src/com/cloud/vm/dao/UserVmDaoImpl.java | 77 ++++---- .../com/cloud/vm/dao/VMInstanceDaoImpl.java | 18 ++ .../com/cloud/vm/MockUserVmManagerImpl.java | 2 +- 55 files changed, 860 insertions(+), 125 deletions(-) create mode 100644 api/src/com/cloud/api/BaseListTaggedResourcesCmd.java diff --git a/api/src/com/cloud/api/BaseListDomainResourcesCmd.java b/api/src/com/cloud/api/BaseListDomainResourcesCmd.java index de4a296fd14..1004d436f66 100644 --- a/api/src/com/cloud/api/BaseListDomainResourcesCmd.java +++ b/api/src/com/cloud/api/BaseListDomainResourcesCmd.java @@ -14,14 +14,17 @@ package com.cloud.api; public abstract class BaseListDomainResourcesCmd extends BaseListCmd { - @Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, description = "If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false") + @Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, description = "If set to false, " + + "list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false") private Boolean listAll; @IdentityMapper(entityTableName = "domain") - @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.LONG, description = "list only resources belonging to the domain specified") + @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.LONG, description = "list only resources" + + " belonging to the domain specified") private Long domainId; - @Parameter(name = ApiConstants.IS_RECURSIVE, type = CommandType.BOOLEAN, description = "defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves.") + @Parameter(name = ApiConstants.IS_RECURSIVE, type = CommandType.BOOLEAN, description = "defaults to false," + + " but if true, lists all resources from the parent specified by the domainId till leaves.") private Boolean recursive; public boolean listAll() { diff --git a/api/src/com/cloud/api/BaseListProjectAndAccountResourcesCmd.java b/api/src/com/cloud/api/BaseListProjectAndAccountResourcesCmd.java index 56e908dfad6..b9defc0f21d 100644 --- a/api/src/com/cloud/api/BaseListProjectAndAccountResourcesCmd.java +++ b/api/src/com/cloud/api/BaseListProjectAndAccountResourcesCmd.java @@ -15,7 +15,7 @@ package com.cloud.api; public abstract class BaseListProjectAndAccountResourcesCmd extends BaseListAccountResourcesCmd { @IdentityMapper(entityTableName = "projects") - @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.LONG, description = "list firewall rules by project") + @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.LONG, description = "list objects by project") private Long projectId; public Long getProjectId() { diff --git a/api/src/com/cloud/api/BaseListTaggedResourcesCmd.java b/api/src/com/cloud/api/BaseListTaggedResourcesCmd.java new file mode 100644 index 00000000000..9a70b107089 --- /dev/null +++ b/api/src/com/cloud/api/BaseListTaggedResourcesCmd.java @@ -0,0 +1,47 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.cloud.exception.InvalidParameterValueException; + +/** + * @author Alena Prokharchyk + */ +public abstract class BaseListTaggedResourcesCmd extends BaseListProjectAndAccountResourcesCmd{ + @Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, description = "List resources by tags (key/value pairs)") + private Map tags; + + public Map getTags() { + Map tagsMap = null; + if (tags != null && !tags.isEmpty()) { + tagsMap = new HashMap(); + Collection servicesCollection = tags.values(); + Iterator iter = servicesCollection.iterator(); + while (iter.hasNext()) { + HashMap services = (HashMap) iter.next(); + String key = services.get("key"); + String value = services.get("value"); + if (value == null) { + throw new InvalidParameterValueException("No value is passed in for key " + key); + } + tagsMap.put(key, value); + } + } + return tagsMap; + } +} diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index e036162d303..0906706ce06 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -297,9 +297,10 @@ public interface ResponseGenerator { /** * @param resourceTag + * @param keyValueOnly TODO * @return */ - ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag); + ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly); Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result); diff --git a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java index db406fe77fb..78b6948b4d3 100644 --- a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java @@ -18,7 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -27,7 +27,7 @@ import com.cloud.api.response.ListResponse; import com.cloud.network.rules.FirewallRule; @Implementation(description="Lists all firewall rules for an IP address.", responseObject=FirewallResponse.class) -public class ListFirewallRulesCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListFirewallRulesCmd.class.getName()); private static final String s_name = "listfirewallrulesresponse"; diff --git a/api/src/com/cloud/api/commands/ListIsosCmd.java b/api/src/com/cloud/api/commands/ListIsosCmd.java index a339b51a09e..7105c47b501 100755 --- a/api/src/com/cloud/api/commands/ListIsosCmd.java +++ b/api/src/com/cloud/api/commands/ListIsosCmd.java @@ -20,7 +20,7 @@ import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; import com.cloud.api.BaseCmd.CommandType; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -33,7 +33,7 @@ import com.cloud.user.UserContext; import com.cloud.utils.Pair; @Implementation(description="Lists all available ISO files.", responseObject=TemplateResponse.class) -public class ListIsosCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListIsosCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListIsosCmd.class.getName()); private static final String s_name = "listisosresponse"; diff --git a/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java b/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java index 25c2570221c..30017854479 100644 --- a/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java @@ -18,8 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -28,7 +27,7 @@ import com.cloud.api.response.LoadBalancerResponse; import com.cloud.network.rules.LoadBalancer; @Implementation(description = "Lists load balancer rules.", responseObject = LoadBalancerResponse.class) -public class ListLoadBalancerRulesCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListLoadBalancerRulesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListLoadBalancerRulesCmd.class.getName()); private static final String s_name = "listloadbalancerrulesresponse"; diff --git a/api/src/com/cloud/api/commands/ListNetworksCmd.java b/api/src/com/cloud/api/commands/ListNetworksCmd.java index 676c453d72c..6b4d451f6d3 100644 --- a/api/src/com/cloud/api/commands/ListNetworksCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworksCmd.java @@ -18,7 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -28,7 +28,7 @@ import com.cloud.network.Network; @Implementation(description="Lists all available networks.", responseObject=NetworkResponse.class) -public class ListNetworksCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListNetworksCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListNetworksCmd.class.getName()); private static final String _name = "listnetworksresponse"; diff --git a/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java b/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java index 9c1b7c88e3b..246d24720e7 100644 --- a/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java @@ -18,7 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -27,7 +27,7 @@ import com.cloud.api.response.ListResponse; import com.cloud.network.rules.PortForwardingRule; @Implementation(description="Lists all port forwarding rules for an IP address.", responseObject=FirewallRuleResponse.class) -public class ListPortForwardingRulesCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListPortForwardingRulesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListPortForwardingRulesCmd.class.getName()); private static final String s_name = "listportforwardingrulesresponse"; diff --git a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java index 60add46ff46..71db8988a95 100644 --- a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java +++ b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java @@ -18,7 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -28,7 +28,7 @@ import com.cloud.async.AsyncJob; import com.cloud.network.IpAddress; @Implementation(description="Lists all public ip addresses", responseObject=IPAddressResponse.class) -public class ListPublicIpAddressesCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListPublicIpAddressesCmd.class.getName()); private static final String s_name = "listpublicipaddressesresponse"; diff --git a/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java b/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java index 7568ad22000..60cb1d200ed 100644 --- a/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java +++ b/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java @@ -17,8 +17,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -28,7 +27,7 @@ import com.cloud.async.AsyncJob; import com.cloud.network.security.SecurityGroupRules; @Implementation(description="Lists security groups", responseObject=SecurityGroupResponse.class) -public class ListSecurityGroupsCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListSecurityGroupsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListSecurityGroupsCmd.class.getName()); private static final String s_name = "listsecuritygroupsresponse"; diff --git a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java index bd293d9f5c1..c606989b21b 100644 --- a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -18,7 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -28,7 +28,7 @@ import com.cloud.async.AsyncJob; import com.cloud.storage.Snapshot; @Implementation(description="Lists all available snapshots for the account.", responseObject=SnapshotResponse.class) -public class ListSnapshotsCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListSnapshotsCmd.class.getName()); private static final String s_name = "listsnapshotsresponse"; diff --git a/api/src/com/cloud/api/commands/ListTagsCmd.java b/api/src/com/cloud/api/commands/ListTagsCmd.java index 8b9eae195ed..bddbcbe0723 100644 --- a/api/src/com/cloud/api/commands/ListTagsCmd.java +++ b/api/src/com/cloud/api/commands/ListTagsCmd.java @@ -58,7 +58,7 @@ public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd{ ListResponse response = new ListResponse(); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = _responseGenerator.createResourceTagResponse(tag); + ResourceTagResponse tagResponse = _responseGenerator.createResourceTagResponse(tag, false); tagResponses.add(tagResponse); } response.setResponses(tagResponses); diff --git a/api/src/com/cloud/api/commands/ListTemplatesCmd.java b/api/src/com/cloud/api/commands/ListTemplatesCmd.java index 6ec50a00280..7df7cf64451 100755 --- a/api/src/com/cloud/api/commands/ListTemplatesCmd.java +++ b/api/src/com/cloud/api/commands/ListTemplatesCmd.java @@ -19,7 +19,8 @@ import java.util.Set; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseCmd.CommandType; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -32,7 +33,7 @@ import com.cloud.user.UserContext; import com.cloud.utils.Pair; @Implementation(description="List all public, private, and privileged templates.", responseObject=TemplateResponse.class) -public class ListTemplatesCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListTemplatesCmd.class.getName()); private static final String s_name = "listtemplatesresponse"; diff --git a/api/src/com/cloud/api/commands/ListVMsCmd.java b/api/src/com/cloud/api/commands/ListVMsCmd.java index 6de18b560f8..e1e527930c5 100755 --- a/api/src/com/cloud/api/commands/ListVMsCmd.java +++ b/api/src/com/cloud/api/commands/ListVMsCmd.java @@ -20,7 +20,7 @@ import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; import com.cloud.api.ApiConstants.VMDetails; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -31,7 +31,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.uservm.UserVm; @Implementation(description="List the virtual machines owned by the account.", responseObject=UserVmResponse.class) -public class ListVMsCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListVMsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVMsCmd.class.getName()); private static final String s_name = "listvirtualmachinesresponse"; diff --git a/api/src/com/cloud/api/commands/ListVolumesCmd.java b/api/src/com/cloud/api/commands/ListVolumesCmd.java index ccea7b910a5..454e4183997 100755 --- a/api/src/com/cloud/api/commands/ListVolumesCmd.java +++ b/api/src/com/cloud/api/commands/ListVolumesCmd.java @@ -18,7 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -28,7 +28,7 @@ import com.cloud.async.AsyncJob; import com.cloud.storage.Volume; @Implementation(description="Lists all volumes.", responseObject=VolumeResponse.class) -public class ListVolumesCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListVolumesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVolumesCmd.class.getName()); private static final String s_name = "listvolumesresponse"; diff --git a/api/src/com/cloud/api/response/FirewallResponse.java b/api/src/com/cloud/api/response/FirewallResponse.java index 7b9243f1f63..74edd00ed5e 100644 --- a/api/src/com/cloud/api/response/FirewallResponse.java +++ b/api/src/com/cloud/api/response/FirewallResponse.java @@ -12,6 +12,8 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.api.response; +import java.util.List; + import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; import com.cloud.utils.IdentityProxy; @@ -48,6 +50,9 @@ public class FirewallResponse extends BaseResponse { @SerializedName(ApiConstants.ICMP_CODE) @Param(description = "error code for this icmp message") private Integer icmpCode; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the rule", responseObject = ResourceTagResponse.class) + private List tags; public void setId(Long id) { this.id.setValue(id); @@ -88,4 +93,8 @@ public class FirewallResponse extends BaseResponse { public void setIcmpCode(Integer icmpCode) { this.icmpCode = icmpCode; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/FirewallRuleResponse.java b/api/src/com/cloud/api/response/FirewallRuleResponse.java index c8af1fc4118..99ea88fb259 100644 --- a/api/src/com/cloud/api/response/FirewallRuleResponse.java +++ b/api/src/com/cloud/api/response/FirewallRuleResponse.java @@ -12,11 +12,14 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.api.response; +import java.util.List; + import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; +@SuppressWarnings("unused") public class FirewallRuleResponse extends BaseResponse{ @SerializedName(ApiConstants.ID) @Param(description="the ID of the port forwarding rule") private IdentityProxy id = new IdentityProxy("firewall_rules"); @@ -57,7 +60,8 @@ public class FirewallRuleResponse extends BaseResponse{ @SerializedName(ApiConstants.CIDR_LIST) @Param(description="the cidr list to forward traffic from") private String cidrList; - + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the rule", responseObject = ResourceTagResponse.class) + private List tags; public Long getId() { return id.getValue(); @@ -163,4 +167,7 @@ public class FirewallRuleResponse extends BaseResponse{ this.cidrList = cidrs; } + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/IPAddressResponse.java b/api/src/com/cloud/api/response/IPAddressResponse.java index 1113dd3a0b1..ad59cf0917c 100644 --- a/api/src/com/cloud/api/response/IPAddressResponse.java +++ b/api/src/com/cloud/api/response/IPAddressResponse.java @@ -13,10 +13,11 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -95,6 +96,9 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the ip belongs to") private IdentityProxy vpcId = new IdentityProxy("vpc"); + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with ip address", responseObject = ResourceTagResponse.class) + private List tags; public void setIpAddress(String ipAddress) { @@ -210,4 +214,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR public void setVpcId(Long vpcId) { this.vpcId.setValue(vpcId); } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/LoadBalancerResponse.java b/api/src/com/cloud/api/response/LoadBalancerResponse.java index 0ea8b7b9305..bab10ab7351 100644 --- a/api/src/com/cloud/api/response/LoadBalancerResponse.java +++ b/api/src/com/cloud/api/response/LoadBalancerResponse.java @@ -12,9 +12,11 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.api.response; +import java.util.List; + import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -79,6 +81,9 @@ public class LoadBalancerResponse extends BaseResponse implements ControlledEnti @SerializedName(ApiConstants.ZONE_ID) @Param(description = "the id of the zone the rule belongs to") private IdentityProxy zoneId = new IdentityProxy("data_center"); + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with load balancer", responseObject = ResourceTagResponse.class) + private List tags; public void setId(Long id) { this.id.setValue(id); @@ -145,5 +150,9 @@ public class LoadBalancerResponse extends BaseResponse implements ControlledEnti public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java index 87eab0ce8fc..b4b8e437517 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -133,6 +133,9 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.CAN_USE_FOR_DEPLOY) @Param(description="list networks available for vm deployment") private Boolean canUseForDeploy; + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with network", responseObject = ResourceTagResponse.class) + private List tags; + public void setId(Long id) { this.id.setValue(id); } @@ -282,4 +285,8 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes public void setCanUseForDeploy(Boolean canUseForDeploy) { this.canUseForDeploy = canUseForDeploy; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/SecurityGroupResponse.java b/api/src/com/cloud/api/response/SecurityGroupResponse.java index d7629ae8c85..3bbfa20b5ba 100644 --- a/api/src/com/cloud/api/response/SecurityGroupResponse.java +++ b/api/src/com/cloud/api/response/SecurityGroupResponse.java @@ -15,8 +15,8 @@ package com.cloud.api.response; import java.util.List; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -51,6 +51,9 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt @SerializedName("egressrule") @Param(description="the list of egress rules associated with the security group", responseObject = SecurityGroupRuleResponse.class) private List egressRules; + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the rule", responseObject = ResourceTagResponse.class) + private List tags; + public void setId(Long id) { this.id.setValue(id); } @@ -126,4 +129,8 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/SnapshotResponse.java b/api/src/com/cloud/api/response/SnapshotResponse.java index 7609b8bea15..284ba1ec29d 100644 --- a/api/src/com/cloud/api/response/SnapshotResponse.java +++ b/api/src/com/cloud/api/response/SnapshotResponse.java @@ -13,11 +13,12 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; import com.cloud.storage.Snapshot; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -75,6 +76,9 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.STATE) @Param(description = "the state of the snapshot. BackedUp means that snapshot is ready to be used; Creating - the snapshot is being allocated on the primary storage; BackingUp - the snapshot is being backed up on secondary storage") private Snapshot.Status state; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class) + private List tags; @Override public Long getObjectId() { @@ -150,4 +154,8 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/TemplateResponse.java b/api/src/com/cloud/api/response/TemplateResponse.java index 3dbd28b28a9..0a83fb17bf0 100755 --- a/api/src/com/cloud/api/response/TemplateResponse.java +++ b/api/src/com/cloud/api/response/TemplateResponse.java @@ -13,6 +13,7 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import java.util.Map; import com.cloud.api.ApiConstants; @@ -124,6 +125,9 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.DETAILS) @Param(description="additional key/value details tied with template") private Map details; + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with tempate", responseObject = ResourceTagResponse.class) + private List tags; + @Override public Long getObjectId() { @@ -273,4 +277,8 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe public void setDetails(Map details) { this.details = details; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/UserVmResponse.java b/api/src/com/cloud/api/response/UserVmResponse.java index f3cf037712c..0b8a3a0bbb1 100755 --- a/api/src/com/cloud/api/response/UserVmResponse.java +++ b/api/src/com/cloud/api/response/UserVmResponse.java @@ -16,8 +16,8 @@ import java.util.Date; import java.util.List; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -150,6 +150,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.INSTANCE_NAME) @Param(description="instance name of the user vm; this parameter is returned to the ROOT admin only", since="3.0.1") private String instanceName; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with vm", responseObject = ResourceTagResponse.class) + private List tags; public void setHypervisor(String hypervisor) { this.hypervisor = hypervisor; @@ -337,4 +340,8 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp public void setInstanceName(String instanceName) { this.instanceName = instanceName; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/VolumeResponse.java b/api/src/com/cloud/api/response/VolumeResponse.java index 5318c1e8df9..7915fc3f041 100755 --- a/api/src/com/cloud/api/response/VolumeResponse.java +++ b/api/src/com/cloud/api/response/VolumeResponse.java @@ -13,10 +13,11 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -146,6 +147,9 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.STATUS) @Param(description="the status of the volume") private String status; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with volume", responseObject = ResourceTagResponse.class) + private List tags; @Override public Long getObjectId() { @@ -289,4 +293,8 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java index d76d19265df..9b1de96d531 100644 --- a/api/src/com/cloud/server/TaggedResourceService.java +++ b/api/src/com/cloud/server/TaggedResourceService.java @@ -54,4 +54,6 @@ public interface TaggedResourceService { * @return */ boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags); + + List listByResourceTypeAndId(TaggedResourceType type, long resourceId); } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 29d5a06af00..d57be217758 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -58,17 +58,17 @@ import com.cloud.network.NetworkManager; import com.cloud.network.NetworkProfile; import com.cloud.network.NetworkRuleConfigVO; import com.cloud.network.NetworkVO; -import com.cloud.network.Site2SiteVpnGatewayVO; -import com.cloud.network.Site2SiteCustomerGatewayVO; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnGatewayVO; import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDomainDao; import com.cloud.network.dao.NetworkRuleConfigDao; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; @@ -82,6 +82,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; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.StatsCollector; import com.cloud.server.TaggedResourceService; @@ -308,7 +309,7 @@ public class ApiDBUtils { } public static List searchForUserVMs(Criteria c, List permittedAccounts) { - return _userVmMgr.searchForUserVMs(c, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), null, false, permittedAccounts, false, null); + return _userVmMgr.searchForUserVMs(c, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), null, false, permittedAccounts, false, null, null); } public static List searchForStoragePools(Criteria c) { @@ -788,4 +789,8 @@ public class ApiDBUtils { public static boolean canUseForDeploy(Network network) { return _networkMgr.canUseForDeploy(network); } + + public static List listByResourceTypeAndId(TaggedResourceType type, long resourceId) { + return _taggedResourceService.listByResourceTypeAndId(type, resourceId); + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 635119e5883..550b89e8d13 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -171,6 +171,7 @@ import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; import com.cloud.server.Criteria; import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; @@ -548,6 +549,16 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setName(snapshot.getName()); snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId())); snapshotResponse.setState(snapshot.getStatus()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Snapshot, snapshot.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + snapshotResponse.setTags(tagResponses); + snapshotResponse.setObjectName("snapshot"); return snapshotResponse; } @@ -819,6 +830,15 @@ public class ApiResponseHelper implements ResponseGenerator { } } + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddr.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + ipResponse.setTags(tagResponses); + ipResponse.setObjectName("ipaddress"); return ipResponse; } @@ -846,6 +866,15 @@ public class ApiResponseHelper implements ResponseGenerator { lbResponse.setState(stateToSet); populateOwner(lbResponse, loadBalancer); lbResponse.setZoneId(publicIp.getDataCenterId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, loadBalancer.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + lbResponse.setTags(tagResponses); lbResponse.setObjectName("loadbalancer"); return lbResponse; @@ -1134,6 +1163,15 @@ public class ApiResponseHelper implements ResponseGenerator { } } + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Volume, volume.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + volResponse.setTags(tagResponses); + volResponse.setExtractable(isExtractable); volResponse.setObjectName("volume"); return volResponse; @@ -1281,6 +1319,16 @@ public class ApiResponseHelper implements ResponseGenerator { if (state.equals(FirewallRule.State.Revoke)) { stateToSet = "Deleting"; } + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PortForwardingRule, fwRule.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + response.setState(stateToSet); response.setObjectName("portforwardingrule"); return response; @@ -1557,6 +1605,15 @@ public class ApiResponseHelper implements ResponseGenerator { userVmResponse.setNics(nicResponses); } + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, userVm.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + userVmResponse.setTags(tagResponses); + IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(userVm.getId()); if (ip != null) { userVmResponse.setPublicIpId(ip.getId()); @@ -1834,6 +1891,21 @@ public class ApiResponseHelper implements ResponseGenerator { Account owner = ApiDBUtils.findAccountById(result.getAccountId()); populateAccount(response, owner.getId()); populateDomain(response, owner.getDomainId()); + + //set tag information + List tags = null; + if (result.getFormat() == ImageFormat.ISO) { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, result.getId()); + } else { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, result.getId()); + } + + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); response.setObjectName("iso"); return response; @@ -2020,6 +2092,20 @@ public class ApiResponseHelper implements ResponseGenerator { templateResponse.setChecksum(template.getChecksum()); templateResponse.setTemplateTag(template.getTemplateTag()); + + //set tag information + List tags = null; + if (template.getFormat() == ImageFormat.ISO) { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, template.getId()); + } else { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, template.getId()); + } + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + templateResponse.setTags(tagResponses); templateResponse.setObjectName("template"); responses.add(templateResponse); @@ -2258,6 +2344,15 @@ public class ApiResponseHelper implements ResponseGenerator { egressRulesResponse.add(ruleData); } } + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, networkGroup.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + netGrpResponse.setTags(tagResponses); + netGrpResponse .setSecurityGroupIngressRules(ingressRulesResponse); netGrpResponse.setSecurityGroupEgressRules(egressRulesResponse); @@ -2265,7 +2360,7 @@ public class ApiResponseHelper implements ResponseGenerator { netGrpResponse.setObjectName("securitygroup"); netGrpResponses.add(netGrpResponse); } - + response.setResponses(netGrpResponses); return response; } @@ -2911,6 +3006,15 @@ public class ApiResponseHelper implements ResponseGenerator { response.setSpecifyIpRanges(network.getSpecifyIpRanges()); response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network)); response.setVpcId(network.getVpcId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Network, network.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); response.setObjectName("network"); return response; @@ -2973,6 +3077,15 @@ public class ApiResponseHelper implements ResponseGenerator { response.setIcmpCode(fwRule.getIcmpCode()); response.setIcmpType(fwRule.getIcmpType()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.FirewallRule, fwRule.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); response.setState(stateToSet); response.setObjectName("firewallrule"); @@ -3128,6 +3241,15 @@ public class ApiResponseHelper implements ResponseGenerator { userVmResponse.setNics(new ArrayList(nicResponses)); userVmResponse.setPublicIpId(userVmData.getPublicIpId()); userVmResponse.setPublicIp(userVmData.getPublicIp()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, userVmData.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + userVmResponse.setTags(tagResponses); return userVmResponse; } @@ -3460,34 +3582,37 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag) { + public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly) { ResourceTagResponse response = new ResourceTagResponse(); response.setKey(resourceTag.getKey()); response.setValue(resourceTag.getValue()); - response.setResourceType(resourceTag.getResourceType().toString()); - response.setId(ApiDBUtils.getUuid(String.valueOf(resourceTag.getResourceId()),resourceTag.getResourceType())); - Long accountId = resourceTag.getAccountId(); - Long domainId = resourceTag.getDomainId(); - if (accountId != null) { - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(resourceTag.getAccountId()); + + if (!keyValueOnly) { + response.setResourceType(resourceTag.getResourceType().toString()); + response.setId(ApiDBUtils.getUuid(String.valueOf(resourceTag.getResourceId()),resourceTag.getResourceType())); + Long accountId = resourceTag.getAccountId(); + Long domainId = resourceTag.getDomainId(); + if (accountId != null) { + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(resourceTag.getAccountId()); - if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - // find the project - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); - response.setProjectId(project.getId()); - response.setProjectName(project.getName()); - } else { - response.setAccountName(account.getAccountName()); + if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + // find the project + Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + response.setProjectId(project.getId()); + response.setProjectName(project.getName()); + } else { + response.setAccountName(account.getAccountName()); + } } + + if (domainId != null) { + response.setDomainId(domainId); + response.setDomainName(ApiDBUtils.findDomainById(domainId).getName()); + } + + response.setCustomer(resourceTag.getCustomer()); } - if (domainId != null) { - response.setDomainId(domainId); - response.setDomainName(ApiDBUtils.findDomainById(domainId).getName()); - } - - response.setCustomer(resourceTag.getCustomer()); - response.setObjectName("tag"); return response; diff --git a/server/src/com/cloud/netapp/dao/VolumeDaoImpl.java b/server/src/com/cloud/netapp/dao/VolumeDaoImpl.java index a540b84bc90..00f67210f84 100644 --- a/server/src/com/cloud/netapp/dao/VolumeDaoImpl.java +++ b/server/src/com/cloud/netapp/dao/VolumeDaoImpl.java @@ -92,4 +92,5 @@ public class VolumeDaoImpl extends GenericDaoBase implemen return listBy(sc, searchFilter); } + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index fc3124252b8..79beb61ee40 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -167,6 +167,9 @@ import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.org.Grouping; import com.cloud.projects.Project; import com.cloud.projects.ProjectManager; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -311,6 +314,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag PrivateIpDao _privateIpDao; @Inject NetworkACLManager _networkACLMgr; + @Inject + ResourceTagDao _resourceTagDao; private final HashMap _systemNetworks = new HashMap(5); private static Long _privateOfferingId = null; @@ -3099,6 +3104,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Boolean specifyIpRanges = cmd.getSpecifyIpRanges(); Long vpcId = cmd.getVpcId(); Boolean canUseForDeploy = cmd.canUseForDeploy(); + Map tags = cmd.getTags(); // 1) default is system to false if not specified // 2) reset parameter to false if it's specified by the regular user @@ -3182,6 +3188,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag zoneSearch.and("networkType", zoneSearch.entity().getNetworkType(), SearchCriteria.Op.EQ); sb.join("zoneSearch", zoneSearch, sb.entity().getDataCenterId(), zoneSearch.entity().getId(), JoinBuilder.JoinType.INNER); sb.and("removed", sb.entity().getRemoved(), Op.NULL); + + if (tags != null && !tags.isEmpty()) { + 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); + 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); + } if (permittedAccounts.isEmpty()) { SearchBuilder domainSearch = _domainDao.createSearchBuilder(); @@ -3203,24 +3221,24 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag networksToReturn .addAll(listDomainLevelNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, domainId)); } if (!permittedAccounts.isEmpty()) { networksToReturn.addAll(listAccountSpecificNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, permittedAccounts)); } else if (domainId == null || listAll) { networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, path, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, path, isRecursive)); } } else { networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, - guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), + guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter); } @@ -3278,7 +3296,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId) { + String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map tags) { SearchCriteria sc = sb.create(); if (isSystem != null) { @@ -3330,6 +3348,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (vpcId != null) { sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId); } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Network.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 sc; } diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index 5423ad91c90..6fc0350ec80 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -23,6 +23,8 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -46,6 +48,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i protected final GenericSearchBuilder RulesByIpCount; protected final FirewallRulesCidrsDaoImpl _firewallRulesCidrsDao = ComponentLocator.inject(FirewallRulesCidrsDaoImpl.class); + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); protected FirewallRulesDaoImpl() { super(); @@ -281,5 +284,25 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i return listBy(sc); } - + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + FirewallRuleVO entry = findById(id); + if (entry != null) { + if (entry.getPurpose() == Purpose.LoadBalancing) { + _tagsDao.removeBy(id, TaggedResourceType.LoadBalancer); + } else if (entry.getPurpose() == Purpose.PortForwarding) { + _tagsDao.removeBy(id, TaggedResourceType.PortForwardingRule); + } else if (entry.getPurpose() == Purpose.Firewall) { + _tagsDao.removeBy(id, TaggedResourceType.FirewallRule); + } + } + boolean result = super.remove(id); + txn.commit(); + return result; + } + } diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index 8e8229ea2e6..42e5f18d459 100755 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -26,6 +26,8 @@ import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDaoImpl; import com.cloud.network.IPAddressVO; import com.cloud.network.IpAddress.State; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -51,6 +53,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen protected final GenericSearchBuilder AllocatedIpCountForAccount; protected final VlanDaoImpl _vlanDao = ComponentLocator.inject(VlanDaoImpl.class); protected GenericSearchBuilder CountFreePublicIps; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); // make it public for JUnit test @@ -322,4 +325,18 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen sc.setParameters("networkId", networkId); return customSearch(sc, null).get(0); } + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + IPAddressVO entry = findById(id); + if (entry != null) { + _tagsDao.removeBy(id, TaggedResourceType.SecurityGroup); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java b/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java index 49685154073..b18395f1f9a 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java +++ b/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java @@ -128,5 +128,5 @@ public class LoadBalancerDaoImpl extends GenericDaoBase im sc.setParameters("state", State.Add.toString(), State.Revoke.toString()); return listBy(sc); } - + } diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index dc2db243b07..d53479fcda3 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -35,6 +35,8 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDaoImpl; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -65,7 +67,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N private final GenericSearchBuilder NetworksCount; final SearchBuilder SourceNATSearch; final GenericSearchBuilder CountByZoneAndURI; - + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class); NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class); @@ -508,4 +510,17 @@ public class NetworkDaoImpl extends GenericDaoBase implements N return findOneBy(sc); } + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + NetworkVO entry = findById(id); + if (entry != null) { + _tagsDao.removeBy(id, TaggedResourceType.Network); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index f271edc1bf4..a2a13132716 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -54,6 +54,9 @@ import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; @@ -63,6 +66,7 @@ import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; @@ -101,6 +105,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma PortForwardingRulesDao _pfRulesDao; @Inject UserVmDao _vmDao; + @Inject + ResourceTagDao _resourceTagDao; private boolean _elbEnabled = false; @@ -196,6 +202,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma public List listFirewallRules(ListFirewallRulesCmd cmd) { Long ipId = cmd.getIpAddressId(); Long id = cmd.getId(); + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -221,6 +228,19 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma sb.and("id", sb.entity().getId(), Op.EQ); sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ); sb.and("purpose", sb.entity().getPurpose(), Op.EQ); + + + if (tags != null && !tags.isEmpty()) { + 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); + 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(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -228,6 +248,16 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (id != null) { sc.setParameters("id", id); } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.FirewallRule.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++; + } + } if (ipId != null) { sc.setParameters("ip", ipId); diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 83e79c28250..6941f5ad639 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -81,6 +81,9 @@ import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.StickinessPolicy; import com.cloud.offering.NetworkOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainService; @@ -158,6 +161,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa ExternalLoadBalancerUsageManager _externalLBUsageMgr; @Inject NetworkServiceMapDao _ntwkSrvcDao; + @Inject + ResourceTagDao _resourceTagDao; private String getLBStickinessCapability(long networkid) { Map> serviceCapabilitiesMap = _networkMgr.getNetworkCapabilities(networkid); @@ -1223,6 +1228,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa String name = cmd.getLoadBalancerRuleName(); String keyword = cmd.getKeyword(); Long instanceId = cmd.getVirtualMachineId(); + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1252,6 +1258,18 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa ipSearch.and("zoneId", ipSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), JoinBuilder.JoinType.INNER); } + + if (tags != null && !tags.isEmpty()) { + 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); + 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(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -1282,6 +1300,17 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa if (zoneId != null) { sc.setJoinParameters("ipSearch", "zoneId", zoneId); } + + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.LoadBalancer.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 _lbDao.search(sc, searchFilter); } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 0d8ef4f16b6..a9edd268211 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -48,6 +48,9 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offering.NetworkOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; @@ -65,7 +68,6 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; -import com.cloud.utils.AnnotationHelper; import com.cloud.vm.Nic; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; @@ -106,6 +108,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { ConfigurationManager _configMgr; @Inject NicDao _nicDao; + @Inject + ResourceTagDao _resourceTagDao; @Override public void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller) { @@ -631,6 +635,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { public List listPortForwardingRules(ListPortForwardingRulesCmd cmd) { Long ipId = cmd.getIpAddressId(); Long id = cmd.getId(); + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -656,6 +661,19 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { sb.and("id", sb.entity().getId(), Op.EQ); sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ); sb.and("purpose", sb.entity().getPurpose(), Op.EQ); + + if (tags != null && !tags.isEmpty()) { + 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); + 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(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -663,6 +681,16 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { if (id != null) { sc.setParameters("id", id); } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.PortForwardingRule.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++; + } + } if (ipId != null) { sc.setParameters("ip", ipId); diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index ba8b6a606b1..7113cb87ba1 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -73,6 +73,9 @@ import com.cloud.network.security.dao.VmRulesetLogDao; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.ProjectManager; import com.cloud.server.ManagementServer; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; @@ -89,6 +92,7 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @@ -151,6 +155,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG ProjectManager _projectMgr; @Inject UsageEventDao _usageEventDao; + @Inject + ResourceTagDao _resourceTagDao; ScheduledExecutorService _executorPool; ScheduledExecutorService _cleanupExecutor; @@ -1089,6 +1095,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG Long id = cmd.getId(); Object keyword = cmd.getKeyword(); List permittedAccounts = new ArrayList(); + Map tags = cmd.getTags(); if (instanceId != null) { UserVmVO userVM = _userVMDao.findById(instanceId); @@ -1113,6 +1120,18 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + + if (tags != null && !tags.isEmpty()) { + 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); + 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(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -1120,6 +1139,16 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG if (id != null) { sc.setParameters("id", id); } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.SecurityGroup.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++; + } + } if (securityGroup != null) { sc.setParameters("name", securityGroup); diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java index 4d37d4bc4c6..e16af3d2e92 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java @@ -17,15 +17,23 @@ import java.util.List; import javax.ejb.Local; import com.cloud.network.security.SecurityGroupVO; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.storage.VolumeVO; +import com.cloud.tags.dao.ResourceTagsDaoImpl; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; @Local(value={SecurityGroupDao.class}) public class SecurityGroupDaoImpl extends GenericDaoBase implements SecurityGroupDao { private SearchBuilder AccountIdSearch; private SearchBuilder AccountIdNameSearch; - private SearchBuilder AccountIdNamesSearch; + private SearchBuilder AccountIdNamesSearch; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); + protected SecurityGroupDaoImpl() { AccountIdSearch = createSearchBuilder(); @@ -84,8 +92,22 @@ public class SecurityGroupDaoImpl extends GenericDaoBase } @Override public int removeByAccountId(long accountId) { - SearchCriteria sc = AccountIdSearch.create(); + SearchCriteria sc = AccountIdSearch.create(); sc.setParameters("accountId", accountId); return expunge(sc); - } + } + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + SecurityGroupVO entry = findById(id); + if (entry != null) { + _tagsDao.removeBy(id, TaggedResourceType.SecurityGroup); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 28323b2cbf1..40b9265318f 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -166,6 +166,7 @@ import com.cloud.projects.Project; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -192,6 +193,8 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.upload.UploadMonitor; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -244,8 +247,6 @@ import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; -import com.cloud.utils.exception.CSExceptionErrorCode; -import com.cloud.utils.AnnotationHelper; import edu.emory.mathcs.backport.java.util.Arrays; import edu.emory.mathcs.backport.java.util.Collections; @@ -302,6 +303,7 @@ public class ManagementServerImpl implements ManagementServer { private final HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; private final Adapters _hostAllocators; private final ConfigurationManager _configMgr; + private final ResourceTagDao _resourceTagDao; @Inject ProjectManager _projectMgr; @@ -377,6 +379,7 @@ public class ManagementServerImpl implements ManagementServer { _ksMgr = locator.getManager(KeystoreManager.class); _resourceMgr = locator.getManager(ResourceManager.class); _configMgr = locator.getManager(ConfigurationManager.class); + _resourceTagDao = locator.getDao(ResourceTagDao.class); _hypervisorCapabilitiesDao = locator.getDao(HypervisorCapabilitiesDao.class); @@ -1251,6 +1254,7 @@ public class ManagementServerImpl implements ManagementServer { public Set> listIsos(ListIsosCmd cmd) throws IllegalArgumentException, InvalidParameterValueException { TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter()); Account caller = UserContext.current().getCaller(); + Map tags = cmd.getTags(); boolean listAll = (caller.getType() != Account.ACCOUNT_TYPE_NORMAL && (isoFilter != null && isoFilter == TemplateFilter.all)); List permittedAccountIds = new ArrayList(); @@ -1265,14 +1269,14 @@ public class ManagementServerImpl implements ManagementServer { HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return listTemplates(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, - cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria); + cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); } @Override public Set> listTemplates(ListTemplatesCmd cmd) throws IllegalArgumentException, InvalidParameterValueException { TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter()); Long id = cmd.getId(); - + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); boolean listAll = (caller.getType() != Account.ACCOUNT_TYPE_NORMAL && (templateFilter != null && templateFilter == TemplateFilter.all)); @@ -1289,11 +1293,11 @@ public class ManagementServerImpl implements ManagementServer { HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return listTemplates(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, showDomr, - cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria); + 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) { + Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { VMTemplateVO template = null; if (templateId != null) { @@ -1329,10 +1333,12 @@ public class ManagementServerImpl implements ManagementServer { Set> templateZonePairSet = new HashSet>(); if (_swiftMgr.isSwiftEnabled()) { if (template == null) { - templateZonePairSet = _templateDao.searchSwiftTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, + templateZonePairSet = _templateDao.searchSwiftTemplates(name, keyword, templateFilter, isIso, + hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller); Set> templateZonePairSet2 = new HashSet>(); - templateZonePairSet2 = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, + templateZonePairSet2 = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, + bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria); for (Pair tmpltPair : templateZonePairSet2) { if (!templateZonePairSet.contains(new Pair(tmpltPair.first(), -1L))) { @@ -1350,7 +1356,8 @@ public class ManagementServerImpl implements ManagementServer { } } else { if (template == null) { - templateZonePairSet = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, + templateZonePairSet = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, + bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria); } else { // if template is not public, perform permission check here @@ -1687,6 +1694,7 @@ public class ManagementServerImpl implements ManagementServer { Boolean sourceNat = cmd.getIsSourceNat(); Boolean staticNat = cmd.getIsStaticNat(); Long vpcId = cmd.getVpcId(); + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1725,6 +1733,19 @@ public class ManagementServerImpl implements ManagementServer { if (keyword != null && address == null) { sb.and("addressLIKE", sb.entity().getAddress(), SearchCriteria.Op.LIKE); } + + if (tags != null && !tags.isEmpty()) { + 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); + 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); + } + SearchBuilder vlanSearch = _vlanDao.createSearchBuilder(); vlanSearch.and("vlanType", vlanSearch.entity().getVlanType(), SearchCriteria.Op.EQ); @@ -1752,6 +1773,16 @@ public class ManagementServerImpl implements ManagementServer { _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sc.setJoinParameters("vlanSearch", "vlanType", vlanType); + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.PublicIpAddress.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++; + } + } if (zone != null) { sc.setParameters("dataCenterId", zone); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index f8ad65cc9b4..33c1df78cf7 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -128,6 +128,7 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.server.ManagementServer; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.Storage.ImageFormat; @@ -152,6 +153,8 @@ import com.cloud.storage.listener.StoragePoolMonitor; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotScheduler; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -316,6 +319,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag protected CheckPointManager _checkPointMgr; @Inject protected DownloadMonitor _downloadMonitor; + @Inject + protected ResourceTagDao _resourceTagDao; @Inject(adapter = StoragePoolAllocator.class) protected Adapters _storagePoolAllocators; @@ -3721,6 +3726,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag String name = cmd.getVolumeName(); String keyword = cmd.getKeyword(); String type = cmd.getType(); + Map tags = cmd.getTags(); Long zoneId = cmd.getZoneId(); Long podId = null; @@ -3760,6 +3766,18 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag vmSearch.and("type", vmSearch.entity().getType(), SearchCriteria.Op.NIN); vmSearch.or("nulltype", vmSearch.entity().getType(), SearchCriteria.Op.NULL); sb.join("vmSearch", vmSearch, sb.entity().getInstanceId(), vmSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER); + + if (tags != null && !tags.isEmpty()) { + 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); + 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); + } // now set the SC criteria... SearchCriteria sc = sb.create(); @@ -3778,6 +3796,16 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } sc.setJoinParameters("diskOfferingSearch", "systemUse", 1); + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Volume.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++; + } + } if (id != null) { sc.setParameters("id", id); diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 297bb13afc8..e13dae2d9a0 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -20,13 +20,15 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; +import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -56,6 +58,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements private final SearchBuilder InstanceIdSearch; private final SearchBuilder StatusSearch; private final GenericSearchBuilder CountSnapshotsByAccount; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); protected final VMInstanceDaoImpl _instanceDao = ComponentLocator.inject(VMInstanceDaoImpl.class); protected final VolumeDaoImpl _volumeDao = ComponentLocator.inject(VolumeDaoImpl.class); @@ -286,4 +289,18 @@ public class SnapshotDaoImpl extends GenericDaoBase implements sc.setParameters("status", (Object[])status); return listBy(sc, null); } + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + SnapshotVO entry = findById(id); + if (entry != null) { + _tagsDao.removeBy(id, TaggedResourceType.Snapshot); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 3b66e3bd287..5a39bd5d16f 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -38,14 +38,18 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Storage; +import com.cloud.storage.Storage.ImageFormat; 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.dao.ResourceTagsDaoImpl; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; import com.cloud.user.Account; import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; @@ -98,6 +102,8 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem private SearchBuilder NameAccountIdSearch; private SearchBuilder PublicIsoSearch; private GenericSearchBuilder CountTemplatesByAccount; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); + private String routerTmpltName; private String consoleProxyTmpltName; @@ -785,17 +791,31 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } @Override + @DB public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); VMTemplateVO template = createForUpdate(); template.setRemoved(new Date()); + if (template != null) { + if (template.getFormat() == ImageFormat.ISO) { + _tagsDao.removeBy(id, TaggedResourceType.ISO); + } else { + _tagsDao.removeBy(id, TaggedResourceType.Template); + } + } - return update(id, template); + boolean result = update(id, template); + txn.commit(); + return result; } + private boolean isAdmin(short accountType) { return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); } + } diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java index 0cbcf398d8e..052a0db482f 100755 --- a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -24,13 +24,16 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume; import com.cloud.storage.Volume.Event; import com.cloud.storage.Volume.State; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; +import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -52,6 +55,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol protected final SearchBuilder InstanceStatesSearch; protected final SearchBuilder AllFieldsSearch; protected GenericSearchBuilder CountByAccount; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?"; protected static final String SELECT_HYPERTYPE_FROM_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?"; @@ -391,4 +395,18 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol SumCount sumCount = results.get(0); return new Pair(sumCount.count, sumCount.sum); } + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + VolumeVO entry = findById(id); + if (entry != null) { + _tagsDao.removeBy(id, TaggedResourceType.Volume); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index b97a7d77ca1..1e4e0aa067d 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -67,6 +67,7 @@ import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Status; import com.cloud.storage.Snapshot.Type; @@ -89,6 +90,8 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -108,6 +111,7 @@ import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @@ -179,6 +183,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma private DomainManager _domainMgr; @Inject private VolumeDao _volumeDao; + @Inject + private ResourceTagDao _resourceTagDao; + String _name; private int _totalRetries; private int _pauseInterval; @@ -894,6 +901,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma String keyword = cmd.getKeyword(); String snapshotTypeStr = cmd.getSnapshotType(); String intervalTypeStr = cmd.getIntervalType(); + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -922,6 +930,18 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("snapshotTypeEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.IN); sb.and("snapshotTypeNEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.NEQ); + + if (tags != null && !tags.isEmpty()) { + 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); + 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(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -929,6 +949,16 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (volumeId != null) { sc.setParameters("volumeId", volumeId); } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Snapshot.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++; + } + } if (name != null) { sc.setParameters("name", "%" + name + "%"); diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 3d3cf27d405..c8aaa3b0deb 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -407,4 +407,10 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager return true; } + + + @Override + public List listByResourceTypeAndId(TaggedResourceType type, long resourceId) { + return _resourceTagDao.listBy(resourceId, type); + } } diff --git a/server/src/com/cloud/tags/dao/ResourceTagDao.java b/server/src/com/cloud/tags/dao/ResourceTagDao.java index a2d38514188..07e359b2978 100644 --- a/server/src/com/cloud/tags/dao/ResourceTagDao.java +++ b/server/src/com/cloud/tags/dao/ResourceTagDao.java @@ -12,6 +12,10 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.tags.dao; +import java.util.List; + +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.tags.ResourceTagVO; import com.cloud.utils.db.GenericDao; @@ -20,4 +24,13 @@ import com.cloud.utils.db.GenericDao; */ public interface ResourceTagDao extends GenericDao{ + /** + * @param resourceId + * @param resourceType + * @return + */ + boolean removeBy(long resourceId, TaggedResourceType resourceType); + + List listBy(long resourceId, TaggedResourceType resourceType); + } diff --git a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java index 0285dad8cda..84ce1e02983 100644 --- a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java +++ b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java @@ -12,10 +12,17 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.tags.dao; +import java.util.List; + import javax.ejb.Local; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.tags.ResourceTagVO; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; /** * @author Alena Prokharchyk @@ -23,7 +30,29 @@ import com.cloud.utils.db.GenericDaoBase; @Local(value = { ResourceTagDao.class }) public class ResourceTagsDaoImpl extends GenericDaoBase implements ResourceTagDao{ + final SearchBuilder AllFieldsSearch; - protected ResourceTagsDaoImpl() { + protected ResourceTagsDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("resourceId", AllFieldsSearch.entity().getResourceId(), Op.EQ); + AllFieldsSearch.and("resourceType", AllFieldsSearch.entity().getResourceType(), Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public boolean removeBy(long resourceId, ResourceTag.TaggedResourceType resourceType) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("resourceId", resourceId); + sc.setParameters("resourceType", resourceType); + remove(sc); + return true; + } + + @Override + public List listBy(long resourceId, TaggedResourceType resourceType) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("resourceId", resourceId); + sc.setParameters("resourceType", resourceType); + return listBy(sc); } } diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 864c589df41..c40a0f51baa 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -91,9 +91,10 @@ public interface UserVmManager extends VirtualMachineGuru, UserVmServi * @param permittedAccounts TODO * @param listAll TODO * @param listProjectResourcesCriteria TODO + * @param tags TODO * @return List of UserVMs. */ - List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria); + List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags); String getChecksum(Long hostId, String templatePath); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index a21f9fdf604..ed53dad8c79 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -145,6 +145,7 @@ import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.server.Criteria; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -178,6 +179,8 @@ import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.user.Account; @@ -213,7 +216,6 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.net.NetUtils; -import com.cloud.utils.AnnotationHelper; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.InstanceGroupDao; import com.cloud.vm.dao.InstanceGroupVMMapDao; @@ -340,6 +342,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager protected ItWorkDao _workDao; @Inject VolumeHostDao _volumeHostDao; + @Inject + ResourceTagDao _resourceTagDao; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; @@ -2888,6 +2892,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager String hypervisor = cmd.getHypervisor(); boolean listAll = cmd.listAll(); Long id = cmd.getId(); + Map tags = cmd.getTags(); Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); @@ -2927,11 +2932,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } c.addCriteria(Criteria.ISADMIN, _accountMgr.isAdmin(caller.getType())); - return searchForUserVMs(c, caller, domainId, isRecursive, permittedAccounts, listAll, listProjectResourcesCriteria); + return searchForUserVMs(c, caller, domainId, isRecursive, permittedAccounts, listAll, listProjectResourcesCriteria, tags); } @Override - public List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria) { + public List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, + List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { Filter searchFilter = new Filter(UserVmVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); SearchBuilder sb = _vmDao.createSearchBuilder(); @@ -2974,6 +2980,18 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager groupSearch.and("groupId", groupSearch.entity().getGroupId(), SearchCriteria.Op.EQ); sb.join("groupSearch", groupSearch, sb.entity().getId(), groupSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); } + + if (tags != null && !tags.isEmpty()) { + 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); + 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); + } if (networkId != null) { SearchBuilder nicSearch = _nicDao.createSearchBuilder(); @@ -2996,6 +3014,16 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.UserVm.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++; + } + } + if (groupId != null && (Long) groupId == -1) { sc.setJoinParameters("vmSearch", "instanceId", (Object) null); } else if (groupId != null) { diff --git a/server/src/com/cloud/vm/dao/UserVmDao.java b/server/src/com/cloud/vm/dao/UserVmDao.java index b6b25183c2a..a7dfabd5f67 100755 --- a/server/src/com/cloud/vm/dao/UserVmDao.java +++ b/server/src/com/cloud/vm/dao/UserVmDao.java @@ -66,4 +66,5 @@ public interface UserVmDao extends GenericDao { public Long countAllocatedVMsForAccount(long accountId); Hashtable listVmDetails(Hashtable userVmData); + } diff --git a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java b/server/src/com/cloud/vm/dao/UserVmDaoImpl.java index 5f91426bb71..6e2b05fdacd 100755 --- a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/server/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -12,36 +12,38 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.vm.dao; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; - -import com.cloud.user.Account; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.db.Attribute; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.NicVO; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.UserVmData.NicData; -import com.cloud.vm.dao.UserVmData.SecurityGroupData; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; +import com.cloud.user.Account; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.Attribute; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.NicVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.dao.UserVmData.NicData; +import com.cloud.vm.dao.UserVmData.SecurityGroupData; @Local(value={UserVmDao.class}) public class UserVmDaoImpl extends GenericDaoBase implements UserVmDao { @@ -64,7 +66,9 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use protected GenericSearchBuilder PodsHavingVmsForAccount; protected SearchBuilder UserVmSearch; - protected final Attribute _updateTimeAttr; + protected final Attribute _updateTimeAttr; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); + private static final String LIST_PODS_HAVING_VMS_FOR_ACCOUNT = "SELECT pod_id FROM cloud.vm_instance WHERE data_center_id = ? AND account_id = ? AND pod_id IS NOT NULL AND (state = 'Running' OR state = 'Stopped') " + "GROUP BY pod_id HAVING count(id) > 0 ORDER BY count(id) DESC"; @@ -540,6 +544,15 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging}); return customSearch(sc, null).get(0); } - + + @Override + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + _tagsDao.removeBy(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 0c7e62219c0..03939ee2b4f 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -28,9 +28,12 @@ import org.apache.log4j.Logger; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDaoImpl; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.Attribute; +import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; @@ -71,6 +74,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem protected GenericSearchBuilder CountRunningByHost; protected GenericSearchBuilder CountRunningByAccount; protected SearchBuilder NetworkTypeSearch; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); protected final Attribute _updateTimeAttr; @@ -545,4 +549,18 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem return listBy(sc); } + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + VMInstanceVO vm = findById(id); + if (vm != null && vm.getType() == Type.User) { + _tagsDao.removeBy(id, TaggedResourceType.UserVm); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/test/com/cloud/vm/MockUserVmManagerImpl.java b/server/test/com/cloud/vm/MockUserVmManagerImpl.java index dd16dc75e4f..a66305eb61c 100644 --- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java +++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java @@ -188,7 +188,7 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana } @Override - public List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria) { + public List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { // TODO Auto-generated method stub return null; }