diff --git a/api/src/com/cloud/api/BaseListDomainResourcesCmd.java b/api/src/com/cloud/api/BaseListDomainResourcesCmd.java index f301d9bea9f..9571e1263c1 100644 --- a/api/src/com/cloud/api/BaseListDomainResourcesCmd.java +++ b/api/src/com/cloud/api/BaseListDomainResourcesCmd.java @@ -18,14 +18,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 8120ad1eb3a..78e70019c9b 100644 --- a/api/src/com/cloud/api/BaseListProjectAndAccountResourcesCmd.java +++ b/api/src/com/cloud/api/BaseListProjectAndAccountResourcesCmd.java @@ -19,7 +19,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 864a9e67188..92b1fb33f75 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -285,9 +285,10 @@ public interface ResponseGenerator { /** * @param resourceTag + * @param keyValueOnly TODO * @return */ - ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag); + ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly); } diff --git a/api/src/com/cloud/api/commands/DeleteTagsCmd.java b/api/src/com/cloud/api/commands/DeleteTagsCmd.java index 402bdb6bf56..df6e173b777 100644 --- a/api/src/com/cloud/api/commands/DeleteTagsCmd.java +++ b/api/src/com/cloud/api/commands/DeleteTagsCmd.java @@ -33,7 +33,6 @@ import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; import com.cloud.event.EventTypes; -import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.TaggedResourceType; /** @@ -44,7 +43,7 @@ import com.cloud.server.ResourceTag.TaggedResourceType; public class DeleteTagsCmd extends BaseAsyncCmd{ public static final Logger s_logger = Logger.getLogger(DeleteTagsCmd.class.getName()); - private static final String s_name = "deleteTagsresponse"; + private static final String s_name = "deletetagsresponse"; // /////////////////////////////////////////////////// // ////////////// API parameters ///////////////////// diff --git a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java index f0bbba66caa..d0729b64087 100644 --- a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java @@ -22,8 +22,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; @@ -32,7 +31,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 93ef1f10e77..35a996e9df3 100755 --- a/api/src/com/cloud/api/commands/ListIsosCmd.java +++ b/api/src/com/cloud/api/commands/ListIsosCmd.java @@ -24,7 +24,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; @@ -37,7 +37,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 d30abdfd3e1..43b05402269 100644 --- a/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java @@ -22,8 +22,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; @@ -32,7 +31,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 8f665b90776..63ed95b5268 100644 --- a/api/src/com/cloud/api/commands/ListNetworksCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworksCmd.java @@ -22,7 +22,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; @@ -32,7 +32,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 e75fae5a16b..499a574bffb 100644 --- a/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java @@ -22,7 +22,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; @@ -30,12 +30,12 @@ import com.cloud.api.response.FirewallRuleResponse; 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 static final Logger s_logger = Logger.getLogger(ListPortForwardingRulesCmd.class.getName()); - - private static final String s_name = "listportforwardingrulesresponse"; - +@Implementation(description="Lists all port forwarding rules for an IP address.", responseObject=FirewallRuleResponse.class) +public class ListPortForwardingRulesCmd extends BaseListTaggedResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListPortForwardingRulesCmd.class.getName()); + + private static final String s_name = "listportforwardingrulesresponse"; + ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java index 9ca8a95ca70..0fecc0eadaa 100644 --- a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java +++ b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java @@ -22,7 +22,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; @@ -31,12 +31,13 @@ import com.cloud.api.response.ListResponse; 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 static final Logger s_logger = Logger.getLogger(ListPublicIpAddressesCmd.class.getName()); - - private static final String s_name = "listpublicipaddressesresponse"; +@Implementation(description="Lists all public ip addresses", responseObject=IPAddressResponse.class) +public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListPublicIpAddressesCmd.class.getName()); + + private static final String s_name = "listpublicipaddressesresponse"; + ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java b/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java index 5891ada1a9c..6da023af848 100644 --- a/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java +++ b/api/src/com/cloud/api/commands/ListSecurityGroupsCmd.java @@ -21,8 +21,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; @@ -31,19 +30,20 @@ import com.cloud.api.response.SecurityGroupResponse; 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 static final Logger s_logger = Logger.getLogger(ListSecurityGroupsCmd.class.getName()); - - private static final String s_name = "listsecuritygroupsresponse"; - - ///////////////////////////////////////////////////// - //////////////// API parameters ///////////////////// - ///////////////////////////////////////////////////// - - @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, description="lists security groups by name") - private String securityGroupName; - + +@Implementation(description="Lists security groups", responseObject=SecurityGroupResponse.class) +public class ListSecurityGroupsCmd extends BaseListTaggedResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListSecurityGroupsCmd.class.getName()); + + private static final String s_name = "listsecuritygroupsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, description="lists security groups by name") + private String securityGroupName; + @IdentityMapper(entityTableName="vm_instance") @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, description="lists security groups by virtual machine id") private Long virtualMachineId; diff --git a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java index 67ea1877dd1..d7b2c9e05f9 100644 --- a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -22,7 +22,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; @@ -31,12 +31,13 @@ import com.cloud.api.response.SnapshotResponse; 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 static final Logger s_logger = Logger.getLogger(ListSnapshotsCmd.class.getName()); - - private static final String s_name = "listsnapshotsresponse"; +@Implementation(description="Lists all available snapshots for the account.", responseObject=SnapshotResponse.class) +public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListSnapshotsCmd.class.getName()); + + private static final String s_name = "listsnapshotsresponse"; + ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/ListTagsCmd.java b/api/src/com/cloud/api/commands/ListTagsCmd.java index 5e7acb5071d..2c226797cd9 100644 --- a/api/src/com/cloud/api/commands/ListTagsCmd.java +++ b/api/src/com/cloud/api/commands/ListTagsCmd.java @@ -63,7 +63,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 82864923f53..c1002b8b458 100755 --- a/api/src/com/cloud/api/commands/ListTemplatesCmd.java +++ b/api/src/com/cloud/api/commands/ListTemplatesCmd.java @@ -23,7 +23,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; @@ -36,7 +37,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 402cd1b6233..acc459bed86 100755 --- a/api/src/com/cloud/api/commands/ListVMsCmd.java +++ b/api/src/com/cloud/api/commands/ListVMsCmd.java @@ -24,7 +24,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; @@ -35,7 +35,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 2f07ea24319..e0393a9b76b 100755 --- a/api/src/com/cloud/api/commands/ListVolumesCmd.java +++ b/api/src/com/cloud/api/commands/ListVolumesCmd.java @@ -22,7 +22,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; @@ -31,12 +31,13 @@ import com.cloud.api.response.VolumeResponse; import com.cloud.async.AsyncJob; import com.cloud.storage.Volume; -@Implementation(description="Lists all volumes.", responseObject=VolumeResponse.class) -public class ListVolumesCmd extends BaseListProjectAndAccountResourcesCmd { - public static final Logger s_logger = Logger.getLogger(ListVolumesCmd.class.getName()); - - private static final String s_name = "listvolumesresponse"; +@Implementation(description="Lists all volumes.", responseObject=VolumeResponse.class) +public class ListVolumesCmd extends BaseListTaggedResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListVolumesCmd.class.getName()); + + private static final String s_name = "listvolumesresponse"; + ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/response/FirewallResponse.java b/api/src/com/cloud/api/response/FirewallResponse.java index 0aa5989af8d..6b68f3ad467 100644 --- a/api/src/com/cloud/api/response/FirewallResponse.java +++ b/api/src/com/cloud/api/response/FirewallResponse.java @@ -16,9 +16,11 @@ // under the License. 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; public class FirewallResponse extends BaseResponse { @@ -51,6 +53,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); @@ -91,7 +96,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 fe1e4aa7642..252ad0dafe6 100644 --- a/api/src/com/cloud/api/response/FirewallRuleResponse.java +++ b/api/src/com/cloud/api/response/FirewallRuleResponse.java @@ -16,11 +16,14 @@ // under the License. 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"); @@ -61,7 +64,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(); @@ -167,4 +171,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 f61494c1373..c1f080ce8d5 100644 --- a/api/src/com/cloud/api/response/IPAddressResponse.java +++ b/api/src/com/cloud/api/response/IPAddressResponse.java @@ -17,10 +17,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") @@ -96,6 +97,9 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR @SerializedName(ApiConstants.PURPOSE) @Param(description="purpose of the IP address. In Acton this value is not null for Ips with isSystem=true, and can have either StaticNat or LB value") private String purpose; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with ip address", responseObject = ResourceTagResponse.class) + private List tags; /* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume") @@ -216,4 +220,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR public void setPurpose(String purpose) { this.purpose = purpose; } + + 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 ab1d67957e0..016bccc7188 100644 --- a/api/src/com/cloud/api/response/LoadBalancerResponse.java +++ b/api/src/com/cloud/api/response/LoadBalancerResponse.java @@ -16,9 +16,11 @@ // under the License. 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") @@ -83,6 +85,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); @@ -149,5 +154,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 4c16240ff8d..17b84b8a03a 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -134,6 +134,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); } @@ -279,4 +282,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 862b0fe203e..5c6deedfb34 100644 --- a/api/src/com/cloud/api/response/SecurityGroupResponse.java +++ b/api/src/com/cloud/api/response/SecurityGroupResponse.java @@ -19,8 +19,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") @@ -55,6 +55,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); } @@ -130,4 +133,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 d945e36df56..71b1b14b8b5 100644 --- a/api/src/com/cloud/api/response/SnapshotResponse.java +++ b/api/src/com/cloud/api/response/SnapshotResponse.java @@ -17,11 +17,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") @@ -79,6 +80,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() { @@ -154,4 +158,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 8a4456c76db..5c3d3399799 100755 --- a/api/src/com/cloud/api/response/TemplateResponse.java +++ b/api/src/com/cloud/api/response/TemplateResponse.java @@ -17,6 +17,7 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import java.util.Map; import com.cloud.api.ApiConstants; @@ -128,6 +129,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() { @@ -277,4 +281,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 e3ec3a3d06d..652e026d72c 100755 --- a/api/src/com/cloud/api/response/UserVmResponse.java +++ b/api/src/com/cloud/api/response/UserVmResponse.java @@ -20,8 +20,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") @@ -154,6 +154,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; @@ -341,4 +344,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 86595252000..b5633908a81 100755 --- a/api/src/com/cloud/api/response/VolumeResponse.java +++ b/api/src/com/cloud/api/response/VolumeResponse.java @@ -17,10 +17,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") @@ -150,6 +151,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() { @@ -292,5 +296,9 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp @Override public void setProjectName(String projectName) { this.projectName = projectName; - } + } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index e11320e4a02..640512b3a32 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -64,4 +64,9 @@ public interface ResourceTag extends ControlledEntity{ */ String getCustomer(); + /** + * @return + */ + String getResourceUuid(); + } diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java index e57b884f903..51a4779de27 100644 --- a/api/src/com/cloud/server/TaggedResourceService.java +++ b/api/src/com/cloud/server/TaggedResourceService.java @@ -60,4 +60,6 @@ public interface TaggedResourceService { * @return */ boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags); + + List listByResourceTypeAndId(TaggedResourceType type, long resourceId); } diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 52e6900d963..35fe56849d9 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -7,8 +7,8 @@ message.action.disable.physical.network=Please confirm that you want to disable #modified labels (begin) ***************************************************************************************** - - +label.memory.mb=Memory (in MB) +label.cpu.mhz=CPU (in MHz) #modified labels (end) ******************************************************************************************* @@ -903,7 +903,6 @@ label.code=Code label.confirmation=Confirmation label.cpu.allocated.for.VMs=CPU Allocated for VMs label.cpu.allocated=CPU Allocated -label.cpu.mhz=CPU label.cpu.utilized=CPU Utilized label.cpu=CPU label.created=Created @@ -1023,7 +1022,6 @@ label.lun=LUN label.manage=Manage label.maximum=Maximum label.memory.allocated=Memory Allocated -label.memory.mb=Memory label.memory.total=Memory Total label.memory.used=Memory Used label.memory=Memory diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDaoImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDaoImpl.java index 9c23410eb0f..4a834294b6f 100644 --- a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDaoImpl.java +++ b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDaoImpl.java @@ -96,4 +96,5 @@ public class VolumeDaoImpl extends GenericDaoBase implemen return listBy(sc, searchFilter); } + } diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/patch b/scripts/vm/hypervisor/xenserver/xcpserver/patch index bc2ba336191..1dd1435b780 100644 --- a/scripts/vm/hypervisor/xenserver/xcpserver/patch +++ b/scripts/vm/hypervisor/xenserver/xcpserver/patch @@ -61,3 +61,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin upgrade_snapshot.sh=..,0755,/opt/xensource/bin cloud-clean-vlan.sh=..,0755,/opt/xensource/bin cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin +getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin +bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin +getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 3d5b14fea82..cfc71dee787 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -81,6 +81,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; @@ -301,7 +302,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) { @@ -766,4 +767,7 @@ public class ApiDBUtils { return _taggedResourceService.getUuid(resourceId, resourceType); } + 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 8c8d53ba524..305fdeb6eb8 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -157,6 +157,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; @@ -533,6 +534,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; } @@ -803,6 +814,15 @@ public class ApiResponseHelper implements ResponseGenerator { } } + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddress.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; } @@ -830,6 +850,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; @@ -1118,6 +1147,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; @@ -1265,6 +1303,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; @@ -1541,6 +1589,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()); @@ -1816,6 +1873,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; @@ -2002,6 +2074,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); @@ -2240,6 +2326,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); @@ -2247,7 +2342,7 @@ public class ApiResponseHelper implements ResponseGenerator { netGrpResponse.setObjectName("securitygroup"); netGrpResponses.add(netGrpResponse); } - + response.setResponses(netGrpResponses); return response; } @@ -2893,6 +2988,15 @@ public class ApiResponseHelper implements ResponseGenerator { response.setSpecifyIpRanges(network.getSpecifyIpRanges()); response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network)); + //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; } @@ -2954,6 +3058,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"); @@ -3076,6 +3189,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; } @@ -3408,34 +3530,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/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index de20374311a..f26d40d92f0 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -163,6 +163,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; @@ -306,6 +309,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkServiceMapDao _ntwkSrvcDao; @Inject StorageNetworkManager _stnwMgr; + @Inject + ResourceTagDao _resourceTagDao; private final HashMap _systemNetworks = new HashMap(5); @@ -2700,6 +2705,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean isRecursive = cmd.isRecursive(); Boolean specifyIpRanges = cmd.getSpecifyIpRanges(); 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 @@ -2783,6 +2789,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(); @@ -2802,22 +2820,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Get domain level networks if (domainId != null) { networksToReturn - .addAll(listDomainLevelNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, - domainId)); + .addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, + guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, + specifyIpRanges, tags), searchFilter,domainId)); } if (!permittedAccounts.isEmpty()) { networksToReturn.addAll(listAccountSpecificNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, tags), searchFilter, permittedAccounts)); } else if (domainId == null || listAll) { networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, tags), searchFilter, path, isRecursive)); } } else { - networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges), + networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, + guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, tags), searchFilter); } @@ -2873,8 +2894,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return hasFreeIps; } - 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) { + + 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, Map tags) { SearchCriteria sc = sb.create(); if (isSystem != null) { @@ -2922,6 +2945,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (specifyIpRanges != null) { sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges); } + + 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 5833bab19b9..8cf9bbfdc9a 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -26,6 +26,8 @@ import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; 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; @@ -49,6 +51,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(); @@ -268,5 +271,25 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i sc.setParameters("ipAddressId", sourceIpId); return customSearch(sc, null).get(0); } - + + @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.removeByIdAndType(id, TaggedResourceType.LoadBalancer); + } else if (entry.getPurpose() == Purpose.PortForwarding) { + _tagsDao.removeByIdAndType(id, TaggedResourceType.PortForwardingRule); + } else if (entry.getPurpose() == Purpose.Firewall) { + _tagsDao.removeByIdAndType(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 6e265df0203..97551849e2a 100755 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -30,6 +30,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; @@ -55,6 +57,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 @@ -312,4 +315,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.removeByIdAndType(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 e08b7869cf0..f624bfa92de 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java +++ b/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java @@ -132,5 +132,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 1285487c20a..04a79b8474e 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -38,6 +38,8 @@ import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; 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; @@ -68,7 +70,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); @@ -486,4 +488,17 @@ public class NetworkDaoImpl extends GenericDaoBase implements N return listBy(sc); } + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + NetworkVO entry = findById(id); + if (entry != null) { + _tagsDao.removeByIdAndType(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 ee0082ee037..c27df891d41 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -58,6 +58,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; @@ -67,6 +70,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; @@ -105,6 +109,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma PortForwardingRulesDao _pfRulesDao; @Inject UserVmDao _vmDao; + @Inject + ResourceTagDao _resourceTagDao; private boolean _elbEnabled = false; @@ -198,6 +204,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(); @@ -223,6 +230,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); @@ -230,6 +250,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 29d6f392391..cefde38732f 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -86,6 +86,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; @@ -162,6 +165,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa ExternalLoadBalancerUsageManager _externalLBUsageMgr; @Inject NetworkServiceMapDao _ntwkSrvcDao; + @Inject + ResourceTagDao _resourceTagDao; private String getLBStickinessCapability(long networkid) { Map> serviceCapabilitiesMap = _networkMgr.getNetworkCapabilities(networkid); @@ -1205,6 +1210,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(); @@ -1234,6 +1240,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); @@ -1264,6 +1282,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 eae922cf5b5..666e2691844 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -52,6 +52,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; @@ -69,7 +72,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; @@ -110,6 +112,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) { @@ -583,6 +587,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(); @@ -608,6 +613,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); @@ -615,6 +633,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 e9fb111d756..a1ed6d73e42 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -77,6 +77,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; @@ -93,6 +96,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; @@ -155,6 +159,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG ProjectManager _projectMgr; @Inject UsageEventDao _usageEventDao; + @Inject + ResourceTagDao _resourceTagDao; ScheduledExecutorService _executorPool; ScheduledExecutorService _cleanupExecutor; @@ -1093,6 +1099,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); @@ -1117,6 +1124,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); @@ -1124,6 +1143,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 a962e85ddb8..0c9bdc57995 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java @@ -21,19 +21,26 @@ import java.util.List; import javax.ejb.Local; import com.cloud.network.security.SecurityGroupVO; +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; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; - -@Local(value={SecurityGroupDao.class}) -public class SecurityGroupDaoImpl extends GenericDaoBase implements SecurityGroupDao { +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; - - protected SecurityGroupDaoImpl() { - AccountIdSearch = createSearchBuilder(); - AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); + + + protected SecurityGroupDaoImpl() { + AccountIdSearch = createSearchBuilder(); + AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.done(); AccountIdNameSearch = createSearchBuilder(); @@ -88,8 +95,23 @@ 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.removeByIdAndType(id, TaggedResourceType.SecurityGroup); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } +} diff --git a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java index a7eeb267793..87c8d21e959 100644 --- a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java +++ b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java @@ -73,8 +73,6 @@ public class ProjectDaoImpl extends GenericDaoBase implements P if (!update(projectId, projectToRemove)) { s_logger.warn("Failed to reset name for the project id=" + projectId + " as a part of project remove"); return false; - } else { - } result = super.remove(projectId); txn.commit(); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 1151fcd97d5..ddcf7514766 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -170,6 +170,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; @@ -196,6 +197,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; @@ -248,6 +251,7 @@ 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 edu.emory.mathcs.backport.java.util.Arrays; import edu.emory.mathcs.backport.java.util.Collections; @@ -303,6 +307,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; @@ -378,6 +383,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); @@ -1252,6 +1258,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(); @@ -1266,14 +1273,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)); @@ -1290,11 +1297,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) { @@ -1330,10 +1337,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))) { @@ -1351,7 +1360,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 @@ -1675,6 +1685,7 @@ public class ManagementServerImpl implements ManagementServer { Long ipId = cmd.getId(); Boolean sourceNat = cmd.getIsSourceNat(); Boolean staticNat = cmd.getIsStaticNat(); + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1712,6 +1723,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); @@ -1739,6 +1763,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 3fe27aeb3f1..8f18b04de4e 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -132,6 +132,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; @@ -156,6 +157,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; @@ -320,6 +323,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; @@ -3725,6 +3730,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; @@ -3764,6 +3770,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(); @@ -3782,6 +3800,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 c0e09bf39d3..ac4bb6fc46d 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -24,13 +24,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; @@ -60,6 +62,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); @@ -290,4 +293,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.removeByIdAndType(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 bb5f5ed9015..6f513a34b90 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -33,6 +33,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.api.BaseCmd; +import com.cloud.configuration.Resource; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.domain.DomainVO; @@ -42,14 +43,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; @@ -103,12 +108,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem private SearchBuilder PublicIsoSearch; private GenericSearchBuilder CountTemplatesByAccount; - private String routerTmpltName; - private String consoleProxyTmpltName; - - protected VMTemplateDaoImpl() { - } - + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); + + + private String routerTmpltName; + private String consoleProxyTmpltName; + + protected VMTemplateDaoImpl() { + } + @Override public List listByPublic() { SearchCriteria sc = PublicSearch.create(); @@ -789,12 +797,25 @@ 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.removeByIdAndType(id, TaggedResourceType.ISO); + } else { + _tagsDao.removeByIdAndType(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) || diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java index 95fa56850de..638d209e5b1 100755 --- a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -28,13 +28,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; @@ -56,6 +59,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 = ?"; @@ -395,4 +399,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.removeByIdAndType(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 b07f7365cb2..50dcf384205 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -71,6 +71,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; @@ -93,6 +94,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; @@ -112,6 +115,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; @@ -183,6 +187,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; @@ -898,6 +905,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(); @@ -926,6 +934,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); @@ -933,6 +953,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/ResourceTagVO.java b/server/src/com/cloud/tags/ResourceTagVO.java index f1750063927..d5b28eb19c9 100644 --- a/server/src/com/cloud/tags/ResourceTagVO.java +++ b/server/src/com/cloud/tags/ResourceTagVO.java @@ -61,6 +61,9 @@ public class ResourceTagVO implements Identity, ResourceTag{ @Column(name="resource_id") long resourceId; + @Column(name="resource_uuid") + private String resourceUuid; + @Column(name="resource_type") @Enumerated(value=EnumType.STRING) private TaggedResourceType resourceType; @@ -81,9 +84,10 @@ public class ResourceTagVO implements Identity, ResourceTag{ * @param resourceId * @param resourceType * @param customer TODO + * @param resourceUuid TODO */ public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, - TaggedResourceType resourceType, String customer) { + TaggedResourceType resourceType, String customer, String resourceUuid) { super(); this.key = key; this.value = value; @@ -93,6 +97,7 @@ public class ResourceTagVO implements Identity, ResourceTag{ this.resourceType = resourceType; this.uuid = UUID.randomUUID().toString(); this.customer = customer; + this.resourceUuid = resourceUuid; } @@ -149,4 +154,9 @@ public class ResourceTagVO implements Identity, ResourceTag{ public String getCustomer() { return customer; } + + @Override + public String getResourceUuid() { + return resourceUuid; + } } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index d84b6b5de61..0386425d569 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -236,10 +236,12 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager for (String tag : tags.keySet()) { for (String resourceId : resourceIds) { Long id = getResourceId(resourceId, resourceType); + String resourceUuid = getUuid(resourceId, resourceType); //check if object exists if (_daoMap.get(resourceType).findById(id) == null) { - throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + + " and type " + resourceType); } Pair accountDomainPair = getAccountDomain(id, resourceType); @@ -257,10 +259,9 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager ResourceTagVO resourceTag = new ResourceTagVO(tag, tags.get(tag), accountDomainPair.first(), accountDomainPair.second(), - id, resourceType, customer); + id, resourceType, customer, resourceUuid); resourceTag = _resourceTagDao.persist(resourceTag); resourceTags.add(resourceTag); - } } @@ -282,14 +283,14 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager if (tableName == null) { throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); } - identiyUUId = _identityDao.getIdentityUuid(tableName, resourceId); - if (identiyUUId != null) { - break; - } + + claz = claz.getSuperclass(); + if (claz == Object.class) { + identiyUUId = _identityDao.getIdentityUuid(tableName, resourceId); + } } catch (Exception ex) { //do nothing here, it might mean uuid field is missing and we have to search further } - claz = claz.getSuperclass(); } if (identiyUUId == null) { @@ -324,7 +325,9 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ); sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ); - sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ); + sb.cp(); sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ); @@ -342,6 +345,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager if (resourceId != null) { sc.setParameters("resourceId", resourceId); + sc.setParameters("resourceUuid", resourceId); } if (resourceType != null) { @@ -362,10 +366,14 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager Account caller = UserContext.current().getCaller(); SearchBuilder sb = _resourceTagDao.createSearchBuilder(); - sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN); + sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN); + sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.IN); + sb.cp(); sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + SearchCriteria sc = sb.create(); sc.setParameters("resourceId", resourceIds.toArray()); + sc.setParameters("resourceUuid", resourceIds.toArray()); sc.setParameters("resourceType", resourceType); List resourceTags = _resourceTagDao.search(sc, null);; @@ -400,6 +408,10 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager } } + if (tagsToRemove.isEmpty()) { + throw new InvalidParameterValueException("Unable to find tags by parameters specified"); + } + //Remove the tags Transaction txn = Transaction.currentTxn(); txn.start(); @@ -411,4 +423,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 efe9595201e..2a5c33928c9 100644 --- a/server/src/com/cloud/tags/dao/ResourceTagDao.java +++ b/server/src/com/cloud/tags/dao/ResourceTagDao.java @@ -16,6 +16,10 @@ // under the License. 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; @@ -24,4 +28,20 @@ import com.cloud.utils.db.GenericDao; */ public interface ResourceTagDao extends GenericDao{ + /** + * @param resourceId + * @param resourceType + * @return + */ + boolean removeByIdAndType(long resourceId, TaggedResourceType resourceType); + + List listBy(long resourceId, TaggedResourceType resourceType); + +// /** +// * @param resourceUuId +// * @param resourceType +// * @return +// */ +// ResourceTag findByUuid(String resourceUuId, TaggedResourceType resourceType); + } diff --git a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java index 7f43a046b35..255f9409263 100644 --- a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java +++ b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java @@ -16,10 +16,17 @@ // under the License. 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 @@ -27,7 +34,38 @@ 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("uuid", AllFieldsSearch.entity().getResourceUuid(), Op.EQ); + AllFieldsSearch.and("resourceType", AllFieldsSearch.entity().getResourceType(), Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public boolean removeByIdAndType(long resourceId, ResourceTag.TaggedResourceType resourceType) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("resourceId", resourceId); + sc.setParameters("resourceType", resourceType); + remove(sc); + return true; + } + +// @Override +// public ResourceTag findByUuid(String resourceUuId, ResourceTag.TaggedResourceType resourceType) { +// SearchCriteria sc = AllFieldsSearch.create(); +// sc.setParameters("uuid", resourceUuId); +// sc.setParameters("resourceType", resourceType); +// return findOneBy(sc); +// } + + @Override + public List listBy(long resourceId, TaggedResourceType resourceType) { + 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 e4896761c54..11d2c64016f 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -95,9 +95,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 87d88a4d7f3..b3fac7076f5 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -149,6 +149,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; @@ -182,6 +183,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; @@ -342,6 +345,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Inject protected ItWorkDao _workDao; VolumeHostDao _volumeHostDao; + @Inject + ResourceTagDao _resourceTagDao; protected ScheduledExecutorService _executor = null; @@ -2888,6 +2893,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 +2933,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 +2981,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 +3015,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 aa09e45ab38..9fbcde377dd 100755 --- a/server/src/com/cloud/vm/dao/UserVmDao.java +++ b/server/src/com/cloud/vm/dao/UserVmDao.java @@ -70,4 +70,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 3ef0bf6bbc7..db1d8776623 100755 --- a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/server/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.vm.dao; + import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -29,6 +30,9 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.configuration.Resource; +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; @@ -47,503 +51,515 @@ 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 { - public static final Logger s_logger = Logger.getLogger(UserVmDaoImpl.class); - - protected final SearchBuilder AccountPodSearch; - protected final SearchBuilder AccountDataCenterSearch; - protected final SearchBuilder AccountSearch; - protected final SearchBuilder HostSearch; - protected final SearchBuilder LastHostSearch; - protected final SearchBuilder HostUpSearch; - protected final SearchBuilder HostRunningSearch; - protected final SearchBuilder StateChangeSearch; - protected final SearchBuilder AccountHostSearch; - - protected final SearchBuilder DestroySearch; - protected SearchBuilder AccountDataCenterVirtualSearch; - protected GenericSearchBuilder CountByAccountPod; - protected GenericSearchBuilder CountByAccount; - protected GenericSearchBuilder PodsHavingVmsForAccount; - - protected SearchBuilder UserVmSearch; + +@Local(value={UserVmDao.class}) +public class UserVmDaoImpl extends GenericDaoBase implements UserVmDao { + public static final Logger s_logger = Logger.getLogger(UserVmDaoImpl.class); + + protected final SearchBuilder AccountPodSearch; + protected final SearchBuilder AccountDataCenterSearch; + protected final SearchBuilder AccountSearch; + protected final SearchBuilder HostSearch; + protected final SearchBuilder LastHostSearch; + protected final SearchBuilder HostUpSearch; + protected final SearchBuilder HostRunningSearch; + protected final SearchBuilder StateChangeSearch; + protected final SearchBuilder AccountHostSearch; + + protected final SearchBuilder DestroySearch; + protected SearchBuilder AccountDataCenterVirtualSearch; + protected GenericSearchBuilder CountByAccountPod; + protected GenericSearchBuilder CountByAccount; + protected GenericSearchBuilder PodsHavingVmsForAccount; + + protected SearchBuilder UserVmSearch; protected final Attribute _updateTimeAttr; - - 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"; - - private static String VM_DETAILS = "select vm_instance.id, " + - "account.id, account.account_name, account.type, domain.name, instance_group.id, instance_group.name," + - "data_center.id, data_center.name, data_center.is_security_group_enabled, host.id, host.name, " + - "vm_template.id, vm_template.name, vm_template.display_text, iso.id, iso.name, " + - "vm_template.enable_password, service_offering.id, disk_offering.name, storage_pool.id, storage_pool.pool_type, " + - "service_offering.cpu, service_offering.speed, service_offering.ram_size, volumes.id, volumes.device_id, volumes.volume_type, security_group.id, security_group.name, " + - "security_group.description, nics.id, nics.ip4_address, nics.default_nic, nics.gateway, nics.network_id, nics.netmask, nics.mac_address, nics.broadcast_uri, nics.isolation_uri, " + - "networks.traffic_type, networks.guest_type, user_ip_address.id, user_ip_address.public_ip_address from vm_instance " + - "left join account on vm_instance.account_id=account.id " + - "left join domain on vm_instance.domain_id=domain.id " + - "left join instance_group_vm_map on vm_instance.id=instance_group_vm_map.instance_id " + - "left join instance_group on instance_group_vm_map.group_id=instance_group.id " + - "left join data_center on vm_instance.data_center_id=data_center.id " + - "left join host on vm_instance.host_id=host.id " + - "left join vm_template on vm_instance.vm_template_id=vm_template.id " + - "left join user_vm on vm_instance.id=user_vm.id " + - "left join vm_template iso on iso.id=user_vm.iso_id " + - "left join service_offering on vm_instance.service_offering_id=service_offering.id " + - "left join disk_offering on vm_instance.service_offering_id=disk_offering.id " + - "left join volumes on vm_instance.id=volumes.instance_id " + - "left join storage_pool on volumes.pool_id=storage_pool.id " + - "left join security_group_vm_map on vm_instance.id=security_group_vm_map.instance_id " + - "left join security_group on security_group_vm_map.security_group_id=security_group.id " + - "left join nics on vm_instance.id=nics.instance_id " + - "left join networks on nics.network_id=networks.id " + - "left join user_ip_address on user_ip_address.vm_id=vm_instance.id " + - "where vm_instance.id in ("; - - private static final int VM_DETAILS_BATCH_SIZE=100; - - protected final UserVmDetailsDaoImpl _detailsDao = ComponentLocator.inject(UserVmDetailsDaoImpl.class); - protected final NicDaoImpl _nicDao = ComponentLocator.inject(NicDaoImpl.class); - - protected UserVmDaoImpl() { - AccountSearch = createSearchBuilder(); - AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountSearch.done(); - - HostSearch = createSearchBuilder(); - HostSearch.and("host", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); - HostSearch.done(); - - LastHostSearch = createSearchBuilder(); - LastHostSearch.and("lastHost", LastHostSearch.entity().getLastHostId(), SearchCriteria.Op.EQ); - LastHostSearch.and("state", LastHostSearch.entity().getState(), SearchCriteria.Op.EQ); - LastHostSearch.done(); - - HostUpSearch = createSearchBuilder(); - HostUpSearch.and("host", HostUpSearch.entity().getHostId(), SearchCriteria.Op.EQ); - HostUpSearch.and("states", HostUpSearch.entity().getState(), SearchCriteria.Op.NIN); - HostUpSearch.done(); - - HostRunningSearch = createSearchBuilder(); - HostRunningSearch.and("host", HostRunningSearch.entity().getHostId(), SearchCriteria.Op.EQ); - HostRunningSearch.and("state", HostRunningSearch.entity().getState(), SearchCriteria.Op.EQ); - HostRunningSearch.done(); - - AccountPodSearch = createSearchBuilder(); - AccountPodSearch.and("account", AccountPodSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountPodSearch.and("pod", AccountPodSearch.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ); - AccountPodSearch.done(); - - AccountDataCenterSearch = createSearchBuilder(); - AccountDataCenterSearch.and("account", AccountDataCenterSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountDataCenterSearch.and("dc", AccountDataCenterSearch.entity().getDataCenterIdToDeployIn(), SearchCriteria.Op.EQ); - AccountDataCenterSearch.done(); - - StateChangeSearch = createSearchBuilder(); - StateChangeSearch.and("id", StateChangeSearch.entity().getId(), SearchCriteria.Op.EQ); - StateChangeSearch.and("states", StateChangeSearch.entity().getState(), SearchCriteria.Op.EQ); - StateChangeSearch.and("host", StateChangeSearch.entity().getHostId(), SearchCriteria.Op.EQ); - StateChangeSearch.and("update", StateChangeSearch.entity().getUpdated(), SearchCriteria.Op.EQ); - StateChangeSearch.done(); - - DestroySearch = createSearchBuilder(); - DestroySearch.and("state", DestroySearch.entity().getState(), SearchCriteria.Op.IN); - DestroySearch.and("updateTime", DestroySearch.entity().getUpdateTime(), SearchCriteria.Op.LT); - DestroySearch.done(); - - AccountHostSearch = createSearchBuilder(); - AccountHostSearch.and("accountId", AccountHostSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountHostSearch.and("hostId", AccountHostSearch.entity().getHostId(), SearchCriteria.Op.EQ); - AccountHostSearch.done(); - - CountByAccountPod = createSearchBuilder(Long.class); - CountByAccountPod.select(null, Func.COUNT, null); - CountByAccountPod.and("account", CountByAccountPod.entity().getAccountId(), SearchCriteria.Op.EQ); - CountByAccountPod.and("pod", CountByAccountPod.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ); - CountByAccountPod.done(); - - CountByAccount = createSearchBuilder(Long.class); - CountByAccount.select(null, Func.COUNT, null); - CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); - CountByAccount.and("type", CountByAccount.entity().getType(), SearchCriteria.Op.EQ); - CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN); - CountByAccount.done(); - - - SearchBuilder nicSearch = _nicDao.createSearchBuilder(); - nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); - nicSearch.and("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); - - AccountDataCenterVirtualSearch = createSearchBuilder(); - AccountDataCenterVirtualSearch.and("account", AccountDataCenterVirtualSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountDataCenterVirtualSearch.and("dc", AccountDataCenterVirtualSearch.entity().getDataCenterIdToDeployIn(), SearchCriteria.Op.EQ); - AccountDataCenterVirtualSearch.join("nicSearch", nicSearch, AccountDataCenterVirtualSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); - AccountDataCenterVirtualSearch.done(); - - - _updateTimeAttr = _allAttributes.get("updateTime"); - assert _updateTimeAttr != null : "Couldn't get this updateTime attribute"; - } + 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"; + + private static String VM_DETAILS = "select vm_instance.id, " + + "account.id, account.account_name, account.type, domain.name, instance_group.id, instance_group.name," + + "data_center.id, data_center.name, data_center.is_security_group_enabled, host.id, host.name, " + + "vm_template.id, vm_template.name, vm_template.display_text, iso.id, iso.name, " + + "vm_template.enable_password, service_offering.id, disk_offering.name, storage_pool.id, storage_pool.pool_type, " + + "service_offering.cpu, service_offering.speed, service_offering.ram_size, volumes.id, volumes.device_id, volumes.volume_type, security_group.id, security_group.name, " + + "security_group.description, nics.id, nics.ip4_address, nics.default_nic, nics.gateway, nics.network_id, nics.netmask, nics.mac_address, nics.broadcast_uri, nics.isolation_uri, " + + "networks.traffic_type, networks.guest_type, user_ip_address.id, user_ip_address.public_ip_address from vm_instance " + + "left join account on vm_instance.account_id=account.id " + + "left join domain on vm_instance.domain_id=domain.id " + + "left join instance_group_vm_map on vm_instance.id=instance_group_vm_map.instance_id " + + "left join instance_group on instance_group_vm_map.group_id=instance_group.id " + + "left join data_center on vm_instance.data_center_id=data_center.id " + + "left join host on vm_instance.host_id=host.id " + + "left join vm_template on vm_instance.vm_template_id=vm_template.id " + + "left join user_vm on vm_instance.id=user_vm.id " + + "left join vm_template iso on iso.id=user_vm.iso_id " + + "left join service_offering on vm_instance.service_offering_id=service_offering.id " + + "left join disk_offering on vm_instance.service_offering_id=disk_offering.id " + + "left join volumes on vm_instance.id=volumes.instance_id " + + "left join storage_pool on volumes.pool_id=storage_pool.id " + + "left join security_group_vm_map on vm_instance.id=security_group_vm_map.instance_id " + + "left join security_group on security_group_vm_map.security_group_id=security_group.id " + + "left join nics on vm_instance.id=nics.instance_id " + + "left join networks on nics.network_id=networks.id " + + "left join user_ip_address on user_ip_address.vm_id=vm_instance.id " + + "where vm_instance.id in ("; + + private static final int VM_DETAILS_BATCH_SIZE=100; + + protected final UserVmDetailsDaoImpl _detailsDao = ComponentLocator.inject(UserVmDetailsDaoImpl.class); + protected final NicDaoImpl _nicDao = ComponentLocator.inject(NicDaoImpl.class); + + protected UserVmDaoImpl() { + AccountSearch = createSearchBuilder(); + AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + AccountSearch.done(); + + HostSearch = createSearchBuilder(); + HostSearch.and("host", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostSearch.done(); + + LastHostSearch = createSearchBuilder(); + LastHostSearch.and("lastHost", LastHostSearch.entity().getLastHostId(), SearchCriteria.Op.EQ); + LastHostSearch.and("state", LastHostSearch.entity().getState(), SearchCriteria.Op.EQ); + LastHostSearch.done(); + + HostUpSearch = createSearchBuilder(); + HostUpSearch.and("host", HostUpSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostUpSearch.and("states", HostUpSearch.entity().getState(), SearchCriteria.Op.NIN); + HostUpSearch.done(); + + HostRunningSearch = createSearchBuilder(); + HostRunningSearch.and("host", HostRunningSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostRunningSearch.and("state", HostRunningSearch.entity().getState(), SearchCriteria.Op.EQ); + HostRunningSearch.done(); + + AccountPodSearch = createSearchBuilder(); + AccountPodSearch.and("account", AccountPodSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + AccountPodSearch.and("pod", AccountPodSearch.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ); + AccountPodSearch.done(); + + AccountDataCenterSearch = createSearchBuilder(); + AccountDataCenterSearch.and("account", AccountDataCenterSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + AccountDataCenterSearch.and("dc", AccountDataCenterSearch.entity().getDataCenterIdToDeployIn(), SearchCriteria.Op.EQ); + AccountDataCenterSearch.done(); + + StateChangeSearch = createSearchBuilder(); + StateChangeSearch.and("id", StateChangeSearch.entity().getId(), SearchCriteria.Op.EQ); + StateChangeSearch.and("states", StateChangeSearch.entity().getState(), SearchCriteria.Op.EQ); + StateChangeSearch.and("host", StateChangeSearch.entity().getHostId(), SearchCriteria.Op.EQ); + StateChangeSearch.and("update", StateChangeSearch.entity().getUpdated(), SearchCriteria.Op.EQ); + StateChangeSearch.done(); + + DestroySearch = createSearchBuilder(); + DestroySearch.and("state", DestroySearch.entity().getState(), SearchCriteria.Op.IN); + DestroySearch.and("updateTime", DestroySearch.entity().getUpdateTime(), SearchCriteria.Op.LT); + DestroySearch.done(); + + AccountHostSearch = createSearchBuilder(); + AccountHostSearch.and("accountId", AccountHostSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + AccountHostSearch.and("hostId", AccountHostSearch.entity().getHostId(), SearchCriteria.Op.EQ); + AccountHostSearch.done(); + + CountByAccountPod = createSearchBuilder(Long.class); + CountByAccountPod.select(null, Func.COUNT, null); + CountByAccountPod.and("account", CountByAccountPod.entity().getAccountId(), SearchCriteria.Op.EQ); + CountByAccountPod.and("pod", CountByAccountPod.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ); + CountByAccountPod.done(); + + CountByAccount = createSearchBuilder(Long.class); + CountByAccount.select(null, Func.COUNT, null); + CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); + CountByAccount.and("type", CountByAccount.entity().getType(), SearchCriteria.Op.EQ); + CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN); + CountByAccount.done(); + + + SearchBuilder nicSearch = _nicDao.createSearchBuilder(); + nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + nicSearch.and("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); + + AccountDataCenterVirtualSearch = createSearchBuilder(); + AccountDataCenterVirtualSearch.and("account", AccountDataCenterVirtualSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + AccountDataCenterVirtualSearch.and("dc", AccountDataCenterVirtualSearch.entity().getDataCenterIdToDeployIn(), SearchCriteria.Op.EQ); + AccountDataCenterVirtualSearch.join("nicSearch", nicSearch, AccountDataCenterVirtualSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); + AccountDataCenterVirtualSearch.done(); + + + _updateTimeAttr = _allAttributes.get("updateTime"); + assert _updateTimeAttr != null : "Couldn't get this updateTime attribute"; + } + + @Override + public List listByAccountAndPod(long accountId, long podId) { + SearchCriteria sc = AccountPodSearch.create(); + sc.setParameters("account", accountId); + sc.setParameters("pod", podId); + + return listIncludingRemovedBy(sc); + } + + @Override + public List listByAccountAndDataCenter(long accountId, long dcId) { + SearchCriteria sc = AccountDataCenterSearch.create(); + sc.setParameters("account", accountId); + sc.setParameters("dc", dcId); + + return listIncludingRemovedBy(sc); + } + + @Override + public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData) { + UserVmVO vo = createForUpdate(); + vo.setDisplayName(displayName); + vo.setHaEnabled(enable); + vo.setGuestOSId(osTypeId); + vo.setUserData(userData); + update(id, vo); + } + + @Override + public List findDestroyedVms(Date date) { + SearchCriteria sc = DestroySearch.create(); + sc.setParameters("state", State.Destroyed, State.Expunging, State.Error); + sc.setParameters("updateTime", date); + + return listBy(sc); + } + + @Override + public List listByAccountId(long id) { + SearchCriteria sc = AccountSearch.create(); + sc.setParameters("account", id); + return listBy(sc); + } + + @Override + public List listByHostId(Long id) { + SearchCriteria sc = HostSearch.create(); + sc.setParameters("host", id); + + return listBy(sc); + } + + @Override + public List listUpByHostId(Long hostId) { + SearchCriteria sc = HostUpSearch.create(); + sc.setParameters("host", hostId); + sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); + return listBy(sc); + } + + @Override + public List listRunningByHostId(long hostId) { + SearchCriteria sc = HostRunningSearch.create(); + sc.setParameters("host", hostId); + sc.setParameters("state", State.Running); + + return listBy(sc); + } + + @Override + public List listVirtualNetworkInstancesByAcctAndZone(long accountId, long dcId, long networkId) { + + SearchCriteria sc = AccountDataCenterVirtualSearch.create(); + sc.setParameters("account", accountId); + sc.setParameters("dc", dcId); + sc.setJoinParameters("nicSearch", "networkId", networkId); + + return listBy(sc); + } + + @Override + public List listByNetworkIdAndStates(long networkId, State... states) { + if (UserVmSearch == null) { + NicDao _nicDao = ComponentLocator.getLocator("management-server").getDao(NicDao.class); + SearchBuilder nicSearch = _nicDao.createSearchBuilder(); + nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + nicSearch.and("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); + + UserVmSearch = createSearchBuilder(); + UserVmSearch.and("states", UserVmSearch.entity().getState(), SearchCriteria.Op.IN); + UserVmSearch.join("nicSearch", nicSearch, UserVmSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); + UserVmSearch.done(); + } + + SearchCriteria sc = UserVmSearch.create(); + if (states != null && states.length != 0) { + sc.setParameters("states", (Object[]) states); + } + sc.setJoinParameters("nicSearch", "networkId", networkId); + + return listBy(sc); + } + + @Override + public List listByLastHostId(Long hostId) { + SearchCriteria sc = LastHostSearch.create(); + sc.setParameters("lastHost", hostId); + sc.setParameters("state", State.Stopped); + return listBy(sc); + } + + @Override + public List listByAccountIdAndHostId(long accountId, long hostId) { + SearchCriteria sc = AccountHostSearch.create(); + sc.setParameters("hostId", hostId); + sc.setParameters("accountId", accountId); + return listBy(sc); + } + + @Override + public void loadDetails(UserVmVO vm) { + Map details = _detailsDao.findDetails(vm.getId()); + vm.setDetails(details); + } + + @Override + public void saveDetails(UserVmVO vm) { + Map details = vm.getDetails(); + if (details == null) { + return; + } + _detailsDao.persist(vm.getId(), details); + } + + @Override + public List listPodIdsHavingVmsforAccount(long zoneId, long accountId){ + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + List result = new ArrayList(); + + try { + String sql = LIST_PODS_HAVING_VMS_FOR_ACCOUNT; + pstmt = txn.prepareAutoCloseStatement(sql); + pstmt.setLong(1, zoneId); + pstmt.setLong(2, accountId); + + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + result.add(rs.getLong(1)); + } + return result; + } catch (SQLException e) { + throw new CloudRuntimeException("DB Exception on: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); + } catch (Throwable e) { + throw new CloudRuntimeException("Caught: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); + } + } + + @Override + public Hashtable listVmDetails(Hashtable userVmDataHash){ + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + + try { + int curr_index=0; + + List userVmDataList = new ArrayList(userVmDataHash.values()); + + if (userVmDataList.size() > VM_DETAILS_BATCH_SIZE){ + pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(VM_DETAILS_BATCH_SIZE)); + while ( (curr_index + VM_DETAILS_BATCH_SIZE) <= userVmDataList.size()){ + // set the vars value + for (int k=1,j=curr_index;j 0){ + userVmData.setGroupId(grp_id); + userVmData.setGroup(rs.getString("instance_group.name")); + } + + //"data_center.id, data_center.name, host.id, host.name, vm_template.id, vm_template.name, vm_template.display_text, vm_template.enable_password, + userVmData.setZoneId(rs.getLong("data_center.id")); + userVmData.setZoneName(rs.getString("data_center.name")); + + userVmData.setHostId(rs.getLong("host.id")); + userVmData.setHostName(rs.getString("host.name")); + + long template_id = rs.getLong("vm_template.id"); + if (template_id > 0){ + userVmData.setTemplateId(template_id); + userVmData.setTemplateName(rs.getString("vm_template.name")); + userVmData.setTemplateDisplayText(rs.getString("vm_template.display_text")); + userVmData.setPasswordEnabled(rs.getBoolean("vm_template.enable_password")); + } + else { + userVmData.setTemplateId(-1L); + userVmData.setTemplateName("ISO Boot"); + userVmData.setTemplateDisplayText("ISO Boot"); + userVmData.setPasswordEnabled(false); + } + + long iso_id = rs.getLong("iso.id"); + if (iso_id > 0){ + userVmData.setIsoId(iso_id); + userVmData.setIsoName(rs.getString("iso.name")); + } + + + //service_offering.id, disk_offering.name, " + //"service_offering.cpu, service_offering.speed, service_offering.ram_size, + userVmData.setServiceOfferingId(rs.getLong("service_offering.id")); + userVmData.setServiceOfferingName(rs.getString("disk_offering.name")); + userVmData.setCpuNumber(rs.getInt("service_offering.cpu")); + userVmData.setCpuSpeed(rs.getInt("service_offering.speed")); + userVmData.setMemory(rs.getInt("service_offering.ram_size")); + + // volumes.device_id, volumes.volume_type, + long vol_id = rs.getLong("volumes.id"); + if (vol_id > 0){ + userVmData.setRootDeviceId(rs.getLong("volumes.device_id")); + userVmData.setRootDeviceType(rs.getString("volumes.volume_type")); + // storage pool + long pool_id = rs.getLong("storage_pool.id"); + if (pool_id > 0){ + userVmData.setRootDeviceType(rs.getString("storage_pool.pool_type")); + } + else { + userVmData.setRootDeviceType("Not created"); + } + } + userVmData.setInitialized(); + } + + + Long securityGroupId = rs.getLong("security_group.id"); + if (securityGroupId != null && securityGroupId.longValue() != 0){ + SecurityGroupData resp = userVmData.newSecurityGroupData(); + resp.setId(rs.getLong("security_group.id")); + resp.setName(rs.getString("security_group.name")); + resp.setDescription(rs.getString("security_group.description")); + resp.setObjectName("securitygroup"); + userVmData.addSecurityGroup(resp); + } + + long nic_id = rs.getLong("nics.id"); + if (nic_id > 0){ + NicData nicResponse = userVmData.newNicData(); + nicResponse.setId(nic_id); + nicResponse.setIpaddress(rs.getString("nics.ip4_address")); + nicResponse.setGateway(rs.getString("nics.gateway")); + nicResponse.setNetmask(rs.getString("nics.netmask")); + nicResponse.setNetworkid(rs.getLong("nics.network_id")); + nicResponse.setMacAddress(rs.getString("nics.mac_address")); + + int account_type = rs.getInt("account.type"); + if (account_type == Account.ACCOUNT_TYPE_ADMIN) { + nicResponse.setBroadcastUri(rs.getString("nics.broadcast_uri")); + nicResponse.setIsolationUri(rs.getString("nics.isolation_uri")); + } + + + nicResponse.setTrafficType(rs.getString("networks.traffic_type")); + nicResponse.setType(rs.getString("networks.guest_type")); + nicResponse.setIsDefault(rs.getBoolean("nics.default_nic")); + nicResponse.setObjectName("nic"); + userVmData.addNic(nicResponse); + } + + long publicIpId = rs.getLong("user_ip_address.id"); + if (publicIpId > 0){ + userVmData.setPublicIpId(publicIpId); + userVmData.setPublicIp(rs.getString("user_ip_address.public_ip_address")); + } + + return userVmData; + } + + public String getQueryBatchAppender(int count){ + StringBuilder sb = new StringBuilder(); + for (int i=0;i sc = CountByAccount.create(); + sc.setParameters("account", accountId); + sc.setParameters("type", VirtualMachine.Type.User); + sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging}); + return customSearch(sc, null).get(0); + } @Override - public List listByAccountAndPod(long accountId, long podId) { - SearchCriteria sc = AccountPodSearch.create(); - sc.setParameters("account", accountId); - sc.setParameters("pod", podId); - - return listIncludingRemovedBy(sc); - } - - @Override - public List listByAccountAndDataCenter(long accountId, long dcId) { - SearchCriteria sc = AccountDataCenterSearch.create(); - sc.setParameters("account", accountId); - sc.setParameters("dc", dcId); - - return listIncludingRemovedBy(sc); - } - - @Override - public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData) { - UserVmVO vo = createForUpdate(); - vo.setDisplayName(displayName); - vo.setHaEnabled(enable); - vo.setGuestOSId(osTypeId); - vo.setUserData(userData); - update(id, vo); - } - - @Override - public List findDestroyedVms(Date date) { - SearchCriteria sc = DestroySearch.create(); - sc.setParameters("state", State.Destroyed, State.Expunging, State.Error); - sc.setParameters("updateTime", date); - - return listBy(sc); - } - - @Override - public List listByAccountId(long id) { - SearchCriteria sc = AccountSearch.create(); - sc.setParameters("account", id); - return listBy(sc); - } - - @Override - public List listByHostId(Long id) { - SearchCriteria sc = HostSearch.create(); - sc.setParameters("host", id); - - return listBy(sc); - } - - @Override - public List listUpByHostId(Long hostId) { - SearchCriteria sc = HostUpSearch.create(); - sc.setParameters("host", hostId); - sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); - return listBy(sc); - } - - @Override - public List listRunningByHostId(long hostId) { - SearchCriteria sc = HostRunningSearch.create(); - sc.setParameters("host", hostId); - sc.setParameters("state", State.Running); - - return listBy(sc); - } - - @Override - public List listVirtualNetworkInstancesByAcctAndZone(long accountId, long dcId, long networkId) { - - SearchCriteria sc = AccountDataCenterVirtualSearch.create(); - sc.setParameters("account", accountId); - sc.setParameters("dc", dcId); - sc.setJoinParameters("nicSearch", "networkId", networkId); - - return listBy(sc); - } - - @Override - public List listByNetworkIdAndStates(long networkId, State... states) { - if (UserVmSearch == null) { - NicDao _nicDao = ComponentLocator.getLocator("management-server").getDao(NicDao.class); - SearchBuilder nicSearch = _nicDao.createSearchBuilder(); - nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); - nicSearch.and("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); - - UserVmSearch = createSearchBuilder(); - UserVmSearch.and("states", UserVmSearch.entity().getState(), SearchCriteria.Op.IN); - UserVmSearch.join("nicSearch", nicSearch, UserVmSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); - UserVmSearch.done(); - } - - SearchCriteria sc = UserVmSearch.create(); - if (states != null && states.length != 0) { - sc.setParameters("states", (Object[]) states); - } - sc.setJoinParameters("nicSearch", "networkId", networkId); - - return listBy(sc); - } - - @Override - public List listByLastHostId(Long hostId) { - SearchCriteria sc = LastHostSearch.create(); - sc.setParameters("lastHost", hostId); - sc.setParameters("state", State.Stopped); - return listBy(sc); - } - - @Override - public List listByAccountIdAndHostId(long accountId, long hostId) { - SearchCriteria sc = AccountHostSearch.create(); - sc.setParameters("hostId", hostId); - sc.setParameters("accountId", accountId); - return listBy(sc); - } - - @Override - public void loadDetails(UserVmVO vm) { - Map details = _detailsDao.findDetails(vm.getId()); - vm.setDetails(details); - } - - @Override - public void saveDetails(UserVmVO vm) { - Map details = vm.getDetails(); - if (details == null) { - return; - } - _detailsDao.persist(vm.getId(), details); - } - - @Override - public List listPodIdsHavingVmsforAccount(long zoneId, long accountId){ - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - - try { - String sql = LIST_PODS_HAVING_VMS_FOR_ACCOUNT; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, zoneId); - pstmt.setLong(2, accountId); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - result.add(rs.getLong(1)); - } - return result; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); - } - } - - @Override - public Hashtable listVmDetails(Hashtable userVmDataHash){ + public boolean remove(Long id) { Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - - try { - int curr_index=0; - - List userVmDataList = new ArrayList(userVmDataHash.values()); - - if (userVmDataList.size() > VM_DETAILS_BATCH_SIZE){ - pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(VM_DETAILS_BATCH_SIZE)); - while ( (curr_index + VM_DETAILS_BATCH_SIZE) <= userVmDataList.size()){ - // set the vars value - for (int k=1,j=curr_index;j 0){ - userVmData.setGroupId(grp_id); - userVmData.setGroup(rs.getString("instance_group.name")); - } - - //"data_center.id, data_center.name, host.id, host.name, vm_template.id, vm_template.name, vm_template.display_text, vm_template.enable_password, - userVmData.setZoneId(rs.getLong("data_center.id")); - userVmData.setZoneName(rs.getString("data_center.name")); - - userVmData.setHostId(rs.getLong("host.id")); - userVmData.setHostName(rs.getString("host.name")); - - long template_id = rs.getLong("vm_template.id"); - if (template_id > 0){ - userVmData.setTemplateId(template_id); - userVmData.setTemplateName(rs.getString("vm_template.name")); - userVmData.setTemplateDisplayText(rs.getString("vm_template.display_text")); - userVmData.setPasswordEnabled(rs.getBoolean("vm_template.enable_password")); - } - else { - userVmData.setTemplateId(-1L); - userVmData.setTemplateName("ISO Boot"); - userVmData.setTemplateDisplayText("ISO Boot"); - userVmData.setPasswordEnabled(false); - } - - long iso_id = rs.getLong("iso.id"); - if (iso_id > 0){ - userVmData.setIsoId(iso_id); - userVmData.setIsoName(rs.getString("iso.name")); - } - - - //service_offering.id, disk_offering.name, " - //"service_offering.cpu, service_offering.speed, service_offering.ram_size, - userVmData.setServiceOfferingId(rs.getLong("service_offering.id")); - userVmData.setServiceOfferingName(rs.getString("disk_offering.name")); - userVmData.setCpuNumber(rs.getInt("service_offering.cpu")); - userVmData.setCpuSpeed(rs.getInt("service_offering.speed")); - userVmData.setMemory(rs.getInt("service_offering.ram_size")); - - // volumes.device_id, volumes.volume_type, - long vol_id = rs.getLong("volumes.id"); - if (vol_id > 0){ - userVmData.setRootDeviceId(rs.getLong("volumes.device_id")); - userVmData.setRootDeviceType(rs.getString("volumes.volume_type")); - // storage pool - long pool_id = rs.getLong("storage_pool.id"); - if (pool_id > 0){ - userVmData.setRootDeviceType(rs.getString("storage_pool.pool_type")); - } - else { - userVmData.setRootDeviceType("Not created"); - } - } - userVmData.setInitialized(); - } - - - Long securityGroupId = rs.getLong("security_group.id"); - if (securityGroupId != null && securityGroupId.longValue() != 0){ - SecurityGroupData resp = userVmData.newSecurityGroupData(); - resp.setId(rs.getLong("security_group.id")); - resp.setName(rs.getString("security_group.name")); - resp.setDescription(rs.getString("security_group.description")); - resp.setObjectName("securitygroup"); - userVmData.addSecurityGroup(resp); - } - - long nic_id = rs.getLong("nics.id"); - if (nic_id > 0){ - NicData nicResponse = userVmData.newNicData(); - nicResponse.setId(nic_id); - nicResponse.setIpaddress(rs.getString("nics.ip4_address")); - nicResponse.setGateway(rs.getString("nics.gateway")); - nicResponse.setNetmask(rs.getString("nics.netmask")); - nicResponse.setNetworkid(rs.getLong("nics.network_id")); - nicResponse.setMacAddress(rs.getString("nics.mac_address")); - - int account_type = rs.getInt("account.type"); - if (account_type == Account.ACCOUNT_TYPE_ADMIN) { - nicResponse.setBroadcastUri(rs.getString("nics.broadcast_uri")); - nicResponse.setIsolationUri(rs.getString("nics.isolation_uri")); - } - - - nicResponse.setTrafficType(rs.getString("networks.traffic_type")); - nicResponse.setType(rs.getString("networks.guest_type")); - nicResponse.setIsDefault(rs.getBoolean("nics.default_nic")); - nicResponse.setObjectName("nic"); - userVmData.addNic(nicResponse); - } - - long publicIpId = rs.getLong("user_ip_address.id"); - if (publicIpId > 0){ - userVmData.setPublicIpId(publicIpId); - userVmData.setPublicIp(rs.getString("user_ip_address.public_ip_address")); - } - - return userVmData; - } - - public String getQueryBatchAppender(int count){ - StringBuilder sb = new StringBuilder(); - for (int i=0;i sc = CountByAccount.create(); - sc.setParameters("account", accountId); - sc.setParameters("type", VirtualMachine.Type.User); - sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging}); - return customSearch(sc, null).get(0); - } - - -} + txn.start(); + _tagsDao.removeByIdAndType(id, TaggedResourceType.UserVm); + boolean result = super.remove(id); + txn.commit(); + return result; + } + +} diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index a21a1b791d9..e743a35b0bf 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -32,9 +32,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; @@ -76,6 +79,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; @@ -550,4 +554,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.removeByIdAndType(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 54ba1f8cb4c..5241eb216a6 100644 --- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java +++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java @@ -189,7 +189,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; } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index afcee3f9f6f..bc8c90606d3 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -2139,6 +2139,7 @@ CREATE TABLE `cloud`.`resource_tags` ( `key` varchar(255), `value` varchar(255), `resource_id` bigint unsigned NOT NULL, + `resource_uuid` varchar(40), `resource_type` varchar(255), `customer` varchar(255), `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', @@ -2146,7 +2147,9 @@ CREATE TABLE `cloud`.`resource_tags` ( PRIMARY KEY (`id`), CONSTRAINT `fk_tags__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), CONSTRAINT `fk_tags__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), - UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`) + UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`), + CONSTRAINT `uc_resource_tags__uuid` UNIQUE (`uuid`), + CONSTRAINT `uc_resource_tags__resource_uuid` UNIQUE (`resource_uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 232784dd1f3..f2d1a0d1558 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -7485,7 +7485,7 @@ div.panel.ui-dialog div.list-view div.fixed-header { color: #FFFFFF; background: url(../images/buttons.png) no-repeat -457px -503px; font-size: 11px; - padding: 6px 24px 6px 9px; + padding: 6px 17px 6px 9px; /*+text-shadow:0px 1px 1px #395065;*/ -moz-text-shadow: 0px 1px 1px #395065; -webkit-text-shadow: 0px 1px 1px #395065;