diff --git a/api/src/org/apache/cloudstack/api/BaseResponseWithTagInformation.java b/api/src/org/apache/cloudstack/api/BaseResponseWithTagInformation.java new file mode 100755 index 00000000000..3d694a3141d --- /dev/null +++ b/api/src/org/apache/cloudstack/api/BaseResponseWithTagInformation.java @@ -0,0 +1,40 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package org.apache.cloudstack.api; + +import java.util.Set; + +import org.apache.cloudstack.api.response.ResourceTagResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public abstract class BaseResponseWithTagInformation extends BaseResponse { + + @SerializedName(ApiConstants.TAGS) + @Param(description = "the list of resource tags associated", responseObject = ResourceTagResponse.class) + protected Set tags; + + public void addTag(ResourceTagResponse tag) { + this.tags.add(tag); + } + + public Set getTags(){ + return this.tags; + } + +} diff --git a/api/src/org/apache/cloudstack/api/response/ResourceTagResponse.java b/api/src/org/apache/cloudstack/api/response/ResourceTagResponse.java index ae61347b480..44325560534 100644 --- a/api/src/org/apache/cloudstack/api/response/ResourceTagResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ResourceTagResponse.java @@ -114,6 +114,10 @@ public class ResourceTagResponse extends BaseResponse implements ControlledViewE return this.key; } + public String getValue() { + return this.value; + } + @Override public int hashCode() { final int prime = 31; diff --git a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java index 3e21043e339..4986f2f6369 100644 --- a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java +++ b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java @@ -24,7 +24,7 @@ import java.util.Set; import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.BaseResponseWithTagInformation; import org.apache.cloudstack.api.EntityReference; import com.cloud.serializer.Param; @@ -33,7 +33,7 @@ import com.cloud.template.VirtualMachineTemplate; @EntityReference(value = VirtualMachineTemplate.class) @SuppressWarnings("unused") -public class TemplateResponse extends BaseResponse implements ControlledViewEntityResponse { +public class TemplateResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse { @SerializedName(ApiConstants.ID) @Param(description = "the template ID") private String id; @@ -175,10 +175,6 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti // @SerializedName("zones") @Param(description="list of zones associated with tempate", responseObject = TemplateZoneResponse.class) // private Set zones; - @SerializedName(ApiConstants.TAGS) - @Param(description = "the list of resource tags associated with tempate", responseObject = ResourceTagResponse.class) - private Set tags; - @SerializedName(ApiConstants.SSHKEY_ENABLED) @Param(description = "true if template is sshkey enabled, false otherwise") private Boolean sshKeyEnabled; @@ -346,10 +342,6 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti this.tags = tags; } - public void addTag(ResourceTagResponse tag) { - this.tags.add(tag); - } - public void setSshKeyEnabled(boolean sshKeyEnabled) { this.sshKeyEnabled = sshKeyEnabled; } @@ -361,4 +353,5 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti public String getZoneId() { return zoneId; } + } diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index e8d1a9ed890..d4e612b001b 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -24,7 +24,7 @@ import java.util.Set; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.BaseResponseWithTagInformation; import org.apache.cloudstack.api.EntityReference; import com.cloud.network.router.VirtualRouter; @@ -35,7 +35,7 @@ import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class}) -public class UserVmResponse extends BaseResponse implements ControlledEntityResponse { +public class UserVmResponse extends BaseResponseWithTagInformation implements ControlledEntityResponse { @SerializedName(ApiConstants.ID) @Param(description = "the ID of the virtual machine") private String id; @@ -244,10 +244,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @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 Set tags; - transient Set tagIds; @SerializedName(ApiConstants.DETAILS) @@ -514,10 +510,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp return instanceName; } - public Set getTags() { - return tags; - } - public String getKeyPairName() { return keyPairName; } @@ -758,10 +750,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp this.tags = tags; } - public void addTag(ResourceTagResponse tag) { - this.tags.add(tag); - } - public void setKeyPairName(String keyPairName) { this.keyPairName = keyPairName; } diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index eeb4af9c9e0..a934563e9fe 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -22,7 +22,7 @@ import java.util.Set; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.BaseResponseWithTagInformation; import org.apache.cloudstack.api.EntityReference; import com.cloud.serializer.Param; @@ -31,7 +31,7 @@ import com.google.gson.annotations.SerializedName; @EntityReference(value = Volume.class) @SuppressWarnings("unused") -public class VolumeResponse extends BaseResponse implements ControlledViewEntityResponse { +public class VolumeResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse { @SerializedName(ApiConstants.ID) @Param(description = "ID of the disk volume") private String id; @@ -212,10 +212,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @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 Set tags; - @SerializedName(ApiConstants.DISPLAY_VOLUME) @Param(description = "an optional field whether to the display the volume to the end user or not.", authorized = {RoleType.Admin}) private Boolean displayVolume; @@ -439,14 +435,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity this.projectName = projectName; } - public void setTags(Set tags) { - this.tags = tags; - } - - public void addTag(ResourceTagResponse tag) { - this.tags.add(tag); - } - public void setDisplayVolume(Boolean displayVm) { this.displayVolume = displayVm; } @@ -522,4 +510,8 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity public void setTemplateDisplayText(String templateDisplayText) { this.templateDisplayText = templateDisplayText; } + + public void setTags(Set tags) { + this.tags = tags; + } } diff --git a/server/src/com/cloud/api/query/dao/GenericDaoBaseWithTagInformation.java b/server/src/com/cloud/api/query/dao/GenericDaoBaseWithTagInformation.java new file mode 100755 index 00000000000..e6760d8a216 --- /dev/null +++ b/server/src/com/cloud/api/query/dao/GenericDaoBaseWithTagInformation.java @@ -0,0 +1,51 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.dao; + +import org.apache.cloudstack.api.BaseResponseWithTagInformation; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.BaseViewWithTagInformationVO; +import com.cloud.api.query.vo.ResourceTagJoinVO; +import com.cloud.utils.db.GenericDaoBase; + +public abstract class GenericDaoBaseWithTagInformation extends GenericDaoBase { + + /** + * Update tag information on baseResponse + * @param baseView base view containing tag information + * @param baseResponse response to update + */ + protected void addTagInformation(T baseView, Z baseResponse) { + ResourceTagJoinVO vtag = new ResourceTagJoinVO(); + vtag.setId(baseView.getTagId()); + vtag.setUuid(baseView.getTagUuid()); + vtag.setKey(baseView.getTagKey()); + vtag.setValue(baseView.getTagValue()); + vtag.setDomainId(baseView.getTagDomainId()); + vtag.setAccountId(baseView.getTagAccountId()); + vtag.setResourceId(baseView.getTagResourceId()); + vtag.setResourceUuid(baseView.getTagResourceUuid()); + vtag.setResourceType(baseView.getTagResourceType()); + vtag.setCustomer(baseView.getTagCustomer()); + vtag.setAccountName(baseView.getTagAccountName()); + vtag.setDomainName(baseView.getTagDomainName()); + vtag.setDomainUuid(baseView.getTagDomainUuid()); + baseResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); + } + +} diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index 5444eca6ba5..38120af38c6 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -46,13 +46,12 @@ import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.utils.Pair; import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component -public class TemplateJoinDaoImpl extends GenericDaoBase implements TemplateJoinDao { +public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation implements TemplateJoinDao { public static final Logger s_logger = Logger.getLogger(TemplateJoinDaoImpl.class); @@ -188,10 +187,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im // update tag information long tag_id = template.getTagId(); if (tag_id > 0) { - ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); - if (vtag != null) { - templateResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); - } + addTagInformation(template, templateResponse); } templateResponse.setObjectName("template"); @@ -257,10 +253,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im // update tag information long tag_id = template.getTagId(); if (tag_id > 0) { - ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); - if (vtag != null) { - templateResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); - } + addTagInformation(template, templateResponse); } return templateResponse; diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 7983065f31a..079da57047d 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -40,7 +40,6 @@ import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.api.ApiDBUtils; -import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.gpu.GPU; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -50,7 +49,6 @@ import com.cloud.user.AccountManager; import com.cloud.user.User; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; -import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.vm.UserVmDetailVO; @@ -61,7 +59,7 @@ import com.cloud.vm.dao.NicSecondaryIpVO; import com.cloud.vm.dao.UserVmDetailsDao; @Component -public class UserVmJoinDaoImpl extends GenericDaoBase implements UserVmJoinDao { +public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation implements UserVmJoinDao { public static final Logger s_logger = Logger.getLogger(UserVmJoinDaoImpl.class); @Inject @@ -283,10 +281,7 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem // update tag information long tag_id = userVm.getTagId(); if (tag_id > 0 && !userVmResponse.containTag(tag_id)) { - ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); - if (vtag != null) { - userVmResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); - } + addTagInformation(userVm, userVmResponse); } if (details.contains(VMDetails.all) || details.contains(VMDetails.affgrp)) { @@ -383,10 +378,7 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem long tag_id = uvo.getTagId(); if (tag_id > 0 && !userVmData.containTag(tag_id)) { - ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); - if (vtag != null) { - userVmData.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); - } + addTagInformation(uvo, userVmData); } Long affinityGroupId = uvo.getAffinityGroupId(); diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java index 54d1ca164e2..73e0c6d6cdd 100644 --- a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java @@ -29,7 +29,6 @@ import org.springframework.stereotype.Component; import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiResponseHelper; -import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.VolumeJoinVO; import com.cloud.offering.ServiceOffering; import com.cloud.storage.Storage; @@ -37,12 +36,11 @@ import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; import com.cloud.user.AccountManager; -import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component -public class VolumeJoinDaoImpl extends GenericDaoBase implements VolumeJoinDao { +public class VolumeJoinDaoImpl extends GenericDaoBaseWithTagInformation implements VolumeJoinDao { public static final Logger s_logger = Logger.getLogger(VolumeJoinDaoImpl.class); @Inject @@ -221,10 +219,7 @@ public class VolumeJoinDaoImpl extends GenericDaoBase implem // update tag information long tag_id = volume.getTagId(); if (tag_id > 0) { - ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); - if (vtag != null) { - volResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); - } + addTagInformation(volume, volResponse); } volResponse.setExtractable(isExtractable); @@ -253,10 +248,7 @@ public class VolumeJoinDaoImpl extends GenericDaoBase implem public VolumeResponse setVolumeResponse(ResponseView view, VolumeResponse volData, VolumeJoinVO vol) { long tag_id = vol.getTagId(); if (tag_id > 0) { - ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); - if (vtag != null) { - volData.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); - } + addTagInformation(vol, volData); } return volData; } diff --git a/server/src/com/cloud/api/query/vo/BaseViewWithTagInformationVO.java b/server/src/com/cloud/api/query/vo/BaseViewWithTagInformationVO.java new file mode 100755 index 00000000000..075cde2d8db --- /dev/null +++ b/server/src/com/cloud/api/query/vo/BaseViewWithTagInformationVO.java @@ -0,0 +1,171 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.vo; + +import javax.persistence.Column; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; + +import com.cloud.server.ResourceTag.ResourceObjectType; + +public abstract class BaseViewWithTagInformationVO extends BaseViewVO { + + @Column(name = "tag_id") + private long tagId; + + @Column(name = "tag_uuid") + private String tagUuid; + + @Column(name = "tag_key") + private String tagKey; + + @Column(name = "tag_value") + private String tagValue; + + @Column(name = "tag_domain_id") + private long tagDomainId; + + @Column(name = "tag_account_id") + private long tagAccountId; + + @Column(name = "tag_resource_id") + private long tagResourceId; + + @Column(name = "tag_resource_uuid") + private String tagResourceUuid; + + @Column(name = "tag_resource_type") + @Enumerated(value = EnumType.STRING) + private ResourceObjectType tagResourceType; + + @Column(name = "tag_customer") + private String tagCustomer; + + @Column(name = "tag_account_name") + private String tagAccountName; + + @Column(name = "tag_domain_uuid") + private String tagDomainUuid; + + @Column(name = "tag_domain_name") + private String tagDomainName; + + public long getTagId() { + return tagId; + } + + public void setTagId(long tagId) { + this.tagId = tagId; + } + + public String getTagUuid() { + return tagUuid; + } + + public void setTagUuid(String tagUuid) { + this.tagUuid = tagUuid; + } + + public String getTagKey() { + return tagKey; + } + + public void setTagKey(String tagKey) { + this.tagKey = tagKey; + } + + public String getTagValue() { + return tagValue; + } + + public void setTagValue(String tagValue) { + this.tagValue = tagValue; + } + + public long getTagDomainId() { + return tagDomainId; + } + + public void setTagDomainId(long tagDomainId) { + this.tagDomainId = tagDomainId; + } + + public long getTagAccountId() { + return tagAccountId; + } + + public void setTagAccountId(long tagAccountId) { + this.tagAccountId = tagAccountId; + } + + public long getTagResourceId() { + return tagResourceId; + } + + public void setTagResourceId(long tagResourceId) { + this.tagResourceId = tagResourceId; + } + + public String getTagResourceUuid() { + return tagResourceUuid; + } + + public void setTagResourceUuid(String tagResourceUuid) { + this.tagResourceUuid = tagResourceUuid; + } + + public ResourceObjectType getTagResourceType() { + return tagResourceType; + } + + public void setTagResourceType(ResourceObjectType tagResourceType) { + this.tagResourceType = tagResourceType; + } + + public String getTagCustomer() { + return tagCustomer; + } + + public void setTagCustomer(String tagCustomer) { + this.tagCustomer = tagCustomer; + } + + public String getTagAccountName() { + return tagAccountName; + } + + public void setTagAccountName(String tagAccountName) { + this.tagAccountName = tagAccountName; + } + + public String getTagDomainUuid() { + return tagDomainUuid; + } + + public void setTagDomainUuid(String tagDomainUuid) { + this.tagDomainUuid = tagDomainUuid; + } + + public String getTagDomainName() { + return tagDomainName; + } + + public void setTagDomainName(String tagDomainName) { + this.tagDomainName = tagDomainName; + } + +} diff --git a/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java b/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java index 2c1ff475095..6758552ed33 100644 --- a/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java @@ -184,4 +184,56 @@ public class ResourceTagJoinVO extends BaseViewVO implements ControlledViewEntit public Class getEntityType() { return ResourceTag.class; } + + public void setId(long id) { + this.id = id; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setKey(String key) { + this.key = key; + } + + public void setValue(String value) { + this.value = value; + } + + public void setResourceId(long resourceId) { + this.resourceId = resourceId; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public void setResourceType(ResourceObjectType resourceType) { + this.resourceType = resourceType; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public void setDomainId(long domainId) { + this.domainId = domainId; + } + + public void setDomainUuid(String domainUuid) { + this.domainUuid = domainUuid; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public void setCustomer(String customer) { + this.customer = customer; + } } diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index 834a9cedd07..c8eed0a4535 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -30,7 +30,6 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -40,7 +39,7 @@ import com.cloud.utils.db.GenericDao; @Entity @Table(name = "template_view") -public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { +public class TemplateJoinVO extends BaseViewWithTagInformationVO implements ControlledViewEntity { @Id @Column(name = "id") @@ -218,37 +217,6 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "detail_value") private String detailValue; - @Column(name = "tag_id") - private long tagId; - - @Column(name = "tag_uuid") - private String tagUuid; - - @Column(name = "tag_key") - private String tagKey; - - @Column(name = "tag_value") - private String tagValue; - - @Column(name = "tag_domain_id") - private long tagDomainId; - - @Column(name = "tag_account_id") - private long tagAccountId; - - @Column(name = "tag_resource_id") - private long tagResourceId; - - @Column(name = "tag_resource_uuid") - private String tagResourceUuid; - - @Column(name = "tag_resource_type") - @Enumerated(value = EnumType.STRING) - private ResourceObjectType tagResourceType; - - @Column(name = "tag_customer") - private String tagCustomer; - @Column(name = "state") @Enumerated(EnumType.STRING) ObjectInDataStoreStateMachine.State state; @@ -343,46 +311,6 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { return templateType; } - public long getTagId() { - return tagId; - } - - public String getTagUuid() { - return tagUuid; - } - - public String getTagKey() { - return tagKey; - } - - public String getTagValue() { - return tagValue; - } - - public long getTagDomainId() { - return tagDomainId; - } - - public long getTagAccountId() { - return tagAccountId; - } - - public long getTagResourceId() { - return tagResourceId; - } - - public String getTagResourceUuid() { - return tagResourceUuid; - } - - public ResourceObjectType getTagResourceType() { - return tagResourceType; - } - - public String getTagCustomer() { - return tagCustomer; - } - public long getDataCenterId() { return dataCenterId; } @@ -547,4 +475,9 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { public Class getEntityType() { return VirtualMachineTemplate.class; } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + } diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index 54a48fb06ae..2847c6b83b7 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -31,7 +31,6 @@ import javax.persistence.Transient; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network.GuestType; import com.cloud.network.Networks.TrafficType; -import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.utils.db.GenericDao; @@ -40,7 +39,7 @@ import com.cloud.vm.VirtualMachine.State; @Entity @Table(name = "user_vm_view") -public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { +public class UserVmJoinVO extends BaseViewWithTagInformationVO implements ControlledViewEntity { @Id @Column(name = "id", updatable = false, nullable = false) @@ -346,37 +345,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "job_status") private int jobStatus; - @Column(name = "tag_id") - private long tagId; - - @Column(name = "tag_uuid") - private String tagUuid; - - @Column(name = "tag_key") - private String tagKey; - - @Column(name = "tag_value") - private String tagValue; - - @Column(name = "tag_domain_id") - private long tagDomainId; - - @Column(name = "tag_account_id") - private long tagAccountId; - - @Column(name = "tag_resource_id") - private long tagResourceId; - - @Column(name = "tag_resource_uuid") - private String tagResourceUuid; - - @Column(name = "tag_resource_type") - @Enumerated(value = EnumType.STRING) - private ResourceObjectType tagResourceType; - - @Column(name = "tag_customer") - private String tagCustomer; - @Column(name = "affinity_group_id") private long affinityGroupId; @@ -776,46 +744,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { return keypairName; } - public long getTagId() { - return tagId; - } - - public String getTagUuid() { - return tagUuid; - } - - public String getTagKey() { - return tagKey; - } - - public String getTagValue() { - return tagValue; - } - - public long getTagDomainId() { - return tagDomainId; - } - - public long getTagAccountId() { - return tagAccountId; - } - - public long getTagResourceId() { - return tagResourceId; - } - - public String getTagResourceUuid() { - return tagResourceUuid; - } - - public ResourceObjectType getTagResourceType() { - return tagResourceType; - } - - public String getTagCustomer() { - return tagCustomer; - } - public boolean isLimitCpuUse() { return limitCpuUse; } @@ -907,4 +835,5 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { public Class getEntityType() { return VirtualMachine.class; } + } diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java index d9c482ce0a5..e39b1b1c412 100644 --- a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java +++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java @@ -28,7 +28,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; @@ -37,7 +36,7 @@ import com.cloud.vm.VirtualMachine; @Entity @Table(name = "volume_view") -public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { +public class VolumeJoinVO extends BaseViewWithTagInformationVO implements ControlledViewEntity { @Id @Column(name = "id") @@ -252,37 +251,6 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "job_status") private int jobStatus; - @Column(name = "tag_id") - private long tagId; - - @Column(name = "tag_uuid") - private String tagUuid; - - @Column(name = "tag_key") - private String tagKey; - - @Column(name = "tag_value") - private String tagValue; - - @Column(name = "tag_domain_id") - private long tagDomainId; - - @Column(name = "tag_account_id") - private long tagAccountId; - - @Column(name = "tag_resource_id") - private long tagResourceId; - - @Column(name = "tag_resource_uuid") - private String tagResourceUuid; - - @Column(name = "tag_resource_type") - @Enumerated(value = EnumType.STRING) - private ResourceObjectType tagResourceType; - - @Column(name = "tag_customer") - private String tagCustomer; - @Column(name = "display_volume", updatable = true, nullable = false) protected boolean displayVolume; @@ -563,46 +531,6 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { return jobStatus; } - public long getTagId() { - return tagId; - } - - public String getTagUuid() { - return tagUuid; - } - - public String getTagKey() { - return tagKey; - } - - public String getTagValue() { - return tagValue; - } - - public long getTagDomainId() { - return tagDomainId; - } - - public long getTagAccountId() { - return tagAccountId; - } - - public long getTagResourceId() { - return tagResourceId; - } - - public String getTagResourceUuid() { - return tagResourceUuid; - } - - public ResourceObjectType getTagResourceType() { - return tagResourceType; - } - - public String getTagCustomer() { - return tagCustomer; - } - public long getDataCenterId() { return dataCenterId; } @@ -636,4 +564,5 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { public Class getEntityType() { return Volume.class; } + } diff --git a/server/test/com/cloud/api/query/dao/GenericDaoBaseWithTagInformationBaseTest.java b/server/test/com/cloud/api/query/dao/GenericDaoBaseWithTagInformationBaseTest.java new file mode 100755 index 00000000000..c7c65f8d935 --- /dev/null +++ b/server/test/com/cloud/api/query/dao/GenericDaoBaseWithTagInformationBaseTest.java @@ -0,0 +1,90 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.dao; + +import static org.junit.Assert.assertEquals; + +import org.apache.cloudstack.api.BaseResponseWithTagInformation; +import org.apache.cloudstack.api.response.ResourceTagResponse; +import org.powermock.api.mockito.PowerMockito; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.BaseViewWithTagInformationVO; +import com.cloud.server.ResourceTag.ResourceObjectType; + +public abstract class GenericDaoBaseWithTagInformationBaseTest { + + private final static long TAG_ID = 1l; + private final static String TAG_KEY = "type"; + private final static String TAG_VALUE = "supported"; + private final static String TAG_UUID = "aaaa-aaaa-aaaa-aaaa"; + private final static ResourceObjectType TAG_RESOURCE_TYPE = ResourceObjectType.Template; + private final static String TAG_RESOURCE_TYPE_STR = "Template"; + private final static String TAG_RESOURCE_UUID = "aaaa-aaaa-aaaa-aaaa"; + private final static long TAG_DOMAIN_ID = 123l; + private final static String TAG_DOMAIN_ID_STR = "123"; + private final static String TAG_DOMAIN_NAME = "aaaa-aaaa-aaaa-aaaa"; + private final static String TAG_CUSTOMER = "aaaa-aaaa-aaaa-aaaa"; + private final static String TAG_ACCOUNT_NAME = "admin"; + + private final static String RESPONSE_OBJECT_NAME = "tag"; + + public void prepareSetup(){ + PowerMockito.spy(ApiDBUtils.class); + PowerMockito.stub(PowerMockito.method(ApiDBUtils.class, "newResourceTagResponse")).toReturn(getResourceTagResponse()); + } + + private ResourceTagResponse getResourceTagResponse(){ + ResourceTagResponse tagResponse = new ResourceTagResponse(); + tagResponse.setKey(TAG_KEY); + tagResponse.setValue(TAG_VALUE); + tagResponse.setObjectName(RESPONSE_OBJECT_NAME); + tagResponse.setResourceType(TAG_RESOURCE_TYPE_STR); + tagResponse.setResourceId(TAG_RESOURCE_UUID); + tagResponse.setDomainId(TAG_DOMAIN_ID_STR); + tagResponse.setDomainName(TAG_DOMAIN_NAME); + tagResponse.setCustomer(TAG_CUSTOMER); + tagResponse.setAccountName(TAG_ACCOUNT_NAME); + return tagResponse; + } + + private void prepareBaseView(long tagId, T baseView){ + baseView.setTagId(tagId); + baseView.setTagKey(TAG_KEY); + baseView.setTagValue(TAG_VALUE); + baseView.setTagUuid(TAG_UUID); + baseView.setTagResourceType(TAG_RESOURCE_TYPE); + baseView.setTagAccountName(TAG_ACCOUNT_NAME); + baseView.setTagDomainId(TAG_DOMAIN_ID); + baseView.setTagDomainName(TAG_DOMAIN_NAME); + baseView.setTagCustomer(TAG_CUSTOMER); + baseView.setTagAccountName(TAG_ACCOUNT_NAME); + } + + public void testUpdateTagInformation(GenericDaoBaseWithTagInformation dao, T baseView, Z baseResponse){ + prepareBaseView(TAG_ID, baseView); + dao.addTagInformation(baseView, baseResponse); + ResourceTagResponse[] responseArray = new ResourceTagResponse[baseResponse.getTags().size()]; + baseResponse.getTags().toArray(responseArray); + assertEquals(1, responseArray.length); + assertEquals(TAG_KEY, responseArray[0].getKey()); + assertEquals(TAG_VALUE, responseArray[0].getValue()); + assertEquals(RESPONSE_OBJECT_NAME, responseArray[0].getObjectName()); + } + +} diff --git a/server/test/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java b/server/test/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java new file mode 100755 index 00000000000..d194e32c0f9 --- /dev/null +++ b/server/test/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.dao; + +import org.apache.cloudstack.api.response.TemplateResponse; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.TemplateJoinVO; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(ApiDBUtils.class) +public class TemplateJoinDaoImplTest extends GenericDaoBaseWithTagInformationBaseTest { + + @InjectMocks + private TemplateJoinDaoImpl _templateJoinDaoImpl; + + private TemplateJoinVO template = new TemplateJoinVO(); + private TemplateResponse templateResponse = new TemplateResponse(); + + @Before + public void setup() { + prepareSetup(); + } + + @Test + public void testUpdateTemplateTagInfo(){ + testUpdateTagInformation(_templateJoinDaoImpl, template, templateResponse); + } + +} \ No newline at end of file diff --git a/server/test/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java b/server/test/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java new file mode 100755 index 00000000000..669143ebf4e --- /dev/null +++ b/server/test/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.dao; + +import org.apache.cloudstack.api.response.UserVmResponse; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.UserVmJoinVO; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(ApiDBUtils.class) +public class UserVmJoinDaoImplTest extends GenericDaoBaseWithTagInformationBaseTest { + + @InjectMocks + private UserVmJoinDaoImpl _userVmJoinDaoImpl; + + private UserVmJoinVO userVm = new UserVmJoinVO(); + private UserVmResponse userVmResponse = new UserVmResponse(); + + @Before + public void setup() { + prepareSetup(); + } + + @Test + public void testUpdateUserVmTagInfo(){ + testUpdateTagInformation(_userVmJoinDaoImpl, userVm, userVmResponse); + } + +} \ No newline at end of file diff --git a/server/test/com/cloud/api/query/dao/VolumeJoinDaoImplTest.java b/server/test/com/cloud/api/query/dao/VolumeJoinDaoImplTest.java new file mode 100755 index 00000000000..b0b0ad22739 --- /dev/null +++ b/server/test/com/cloud/api/query/dao/VolumeJoinDaoImplTest.java @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.dao; + +import org.apache.cloudstack.api.response.VolumeResponse; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.VolumeJoinVO; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(ApiDBUtils.class) +public class VolumeJoinDaoImplTest extends GenericDaoBaseWithTagInformationBaseTest { + + @InjectMocks + private VolumeJoinDaoImpl _volumeJoinDaoImpl; + + private VolumeJoinVO volume = new VolumeJoinVO(); + private VolumeResponse volumeResponse = new VolumeResponse(); + + @Before + public void setup() { + prepareSetup(); + } + + @Test + public void testUpdateVolumeTagInfo(){ + testUpdateTagInformation(_volumeJoinDaoImpl, volume, volumeResponse); + } + +} diff --git a/setup/db/db/schema-481to490.sql b/setup/db/db/schema-481to490.sql index 0f27e455823..cebe6056850 100644 --- a/setup/db/db/schema-481to490.sql +++ b/setup/db/db/schema-481to490.sql @@ -21,3 +21,402 @@ ALTER TABLE `event` ADD INDEX `archived` (`archived`); ALTER TABLE `event` ADD INDEX `state` (`state`); + +DROP VIEW IF EXISTS `cloud`.`template_view`; +CREATE + ALGORITHM = UNDEFINED + DEFINER = `cloud`@`%` + SQL SECURITY DEFINER +VIEW `template_view` AS + SELECT + `vm_template`.`id` AS `id`, + `vm_template`.`uuid` AS `uuid`, + `vm_template`.`unique_name` AS `unique_name`, + `vm_template`.`name` AS `name`, + `vm_template`.`public` AS `public`, + `vm_template`.`featured` AS `featured`, + `vm_template`.`type` AS `type`, + `vm_template`.`hvm` AS `hvm`, + `vm_template`.`bits` AS `bits`, + `vm_template`.`url` AS `url`, + `vm_template`.`format` AS `format`, + `vm_template`.`created` AS `created`, + `vm_template`.`checksum` AS `checksum`, + `vm_template`.`display_text` AS `display_text`, + `vm_template`.`enable_password` AS `enable_password`, + `vm_template`.`dynamically_scalable` AS `dynamically_scalable`, + `vm_template`.`state` AS `template_state`, + `vm_template`.`guest_os_id` AS `guest_os_id`, + `guest_os`.`uuid` AS `guest_os_uuid`, + `guest_os`.`display_name` AS `guest_os_name`, + `vm_template`.`bootable` AS `bootable`, + `vm_template`.`prepopulate` AS `prepopulate`, + `vm_template`.`cross_zones` AS `cross_zones`, + `vm_template`.`hypervisor_type` AS `hypervisor_type`, + `vm_template`.`extractable` AS `extractable`, + `vm_template`.`template_tag` AS `template_tag`, + `vm_template`.`sort_key` AS `sort_key`, + `vm_template`.`removed` AS `removed`, + `vm_template`.`enable_sshkey` AS `enable_sshkey`, + `source_template`.`id` AS `source_template_id`, + `source_template`.`uuid` AS `source_template_uuid`, + `account`.`id` AS `account_id`, + `account`.`uuid` AS `account_uuid`, + `account`.`account_name` AS `account_name`, + `account`.`type` AS `account_type`, + `domain`.`id` AS `domain_id`, + `domain`.`uuid` AS `domain_uuid`, + `domain`.`name` AS `domain_name`, + `domain`.`path` AS `domain_path`, + `projects`.`id` AS `project_id`, + `projects`.`uuid` AS `project_uuid`, + `projects`.`name` AS `project_name`, + `data_center`.`id` AS `data_center_id`, + `data_center`.`uuid` AS `data_center_uuid`, + `data_center`.`name` AS `data_center_name`, + `launch_permission`.`account_id` AS `lp_account_id`, + `template_store_ref`.`store_id` AS `store_id`, + `image_store`.`scope` AS `store_scope`, + `template_store_ref`.`state` AS `state`, + `template_store_ref`.`download_state` AS `download_state`, + `template_store_ref`.`download_pct` AS `download_pct`, + `template_store_ref`.`error_str` AS `error_str`, + `template_store_ref`.`size` AS `size`, + `template_store_ref`.`destroyed` AS `destroyed`, + `template_store_ref`.`created` AS `created_on_store`, + `vm_template_details`.`name` AS `detail_name`, + `vm_template_details`.`value` AS `detail_value`, + `resource_tags`.`id` AS `tag_id`, + `resource_tags`.`uuid` AS `tag_uuid`, + `resource_tags`.`key` AS `tag_key`, + `resource_tags`.`value` AS `tag_value`, + `resource_tags`.`domain_id` AS `tag_domain_id`, + `domain`.`uuid` AS `tag_domain_uuid`, + `domain`.`name` AS `tag_domain_name`, + `resource_tags`.`account_id` AS `tag_account_id`, + `account`.`account_name` AS `tag_account_name`, + `resource_tags`.`resource_id` AS `tag_resource_id`, + `resource_tags`.`resource_uuid` AS `tag_resource_uuid`, + `resource_tags`.`resource_type` AS `tag_resource_type`, + `resource_tags`.`customer` AS `tag_customer`, + CONCAT(`vm_template`.`id`, + '_', + IFNULL(`data_center`.`id`, 0)) AS `temp_zone_pair` + FROM + ((((((((((((`vm_template` + JOIN `guest_os` ON ((`guest_os`.`id` = `vm_template`.`guest_os_id`))) + JOIN `account` ON ((`account`.`id` = `vm_template`.`account_id`))) + JOIN `domain` ON ((`domain`.`id` = `account`.`domain_id`))) + LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`))) + LEFT JOIN `vm_template_details` ON ((`vm_template_details`.`template_id` = `vm_template`.`id`))) + LEFT JOIN `vm_template` `source_template` ON ((`source_template`.`id` = `vm_template`.`source_template_id`))) + LEFT JOIN `template_store_ref` ON (((`template_store_ref`.`template_id` = `vm_template`.`id`) + AND (`template_store_ref`.`store_role` = 'Image') + AND (`template_store_ref`.`destroyed` = 0)))) + LEFT JOIN `image_store` ON ((ISNULL(`image_store`.`removed`) + AND (`template_store_ref`.`store_id` IS NOT NULL) + AND (`image_store`.`id` = `template_store_ref`.`store_id`)))) + LEFT JOIN `template_zone_ref` ON (((`template_zone_ref`.`template_id` = `vm_template`.`id`) + AND ISNULL(`template_store_ref`.`store_id`) + AND ISNULL(`template_zone_ref`.`removed`)))) + LEFT JOIN `data_center` ON (((`image_store`.`data_center_id` = `data_center`.`id`) + OR (`template_zone_ref`.`zone_id` = `data_center`.`id`)))) + LEFT JOIN `launch_permission` ON ((`launch_permission`.`template_id` = `vm_template`.`id`))) + LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_template`.`id`) + AND ((`resource_tags`.`resource_type` = 'Template') + OR (`resource_tags`.`resource_type` = 'ISO'))))); + +DROP VIEW IF EXISTS `cloud`.`volume_view`; +CREATE + ALGORITHM = UNDEFINED + DEFINER = `cloud`@`%` + SQL SECURITY DEFINER +VIEW `volume_view` AS + SELECT + `volumes`.`id` AS `id`, + `volumes`.`uuid` AS `uuid`, + `volumes`.`name` AS `name`, + `volumes`.`device_id` AS `device_id`, + `volumes`.`volume_type` AS `volume_type`, + `volumes`.`provisioning_type` AS `provisioning_type`, + `volumes`.`size` AS `size`, + `volumes`.`min_iops` AS `min_iops`, + `volumes`.`max_iops` AS `max_iops`, + `volumes`.`created` AS `created`, + `volumes`.`state` AS `state`, + `volumes`.`attached` AS `attached`, + `volumes`.`removed` AS `removed`, + `volumes`.`pod_id` AS `pod_id`, + `volumes`.`display_volume` AS `display_volume`, + `volumes`.`format` AS `format`, + `volumes`.`path` AS `path`, + `volumes`.`chain_info` AS `chain_info`, + `account`.`id` AS `account_id`, + `account`.`uuid` AS `account_uuid`, + `account`.`account_name` AS `account_name`, + `account`.`type` AS `account_type`, + `domain`.`id` AS `domain_id`, + `domain`.`uuid` AS `domain_uuid`, + `domain`.`name` AS `domain_name`, + `domain`.`path` AS `domain_path`, + `projects`.`id` AS `project_id`, + `projects`.`uuid` AS `project_uuid`, + `projects`.`name` AS `project_name`, + `data_center`.`id` AS `data_center_id`, + `data_center`.`uuid` AS `data_center_uuid`, + `data_center`.`name` AS `data_center_name`, + `data_center`.`networktype` AS `data_center_type`, + `vm_instance`.`id` AS `vm_id`, + `vm_instance`.`uuid` AS `vm_uuid`, + `vm_instance`.`name` AS `vm_name`, + `vm_instance`.`state` AS `vm_state`, + `vm_instance`.`vm_type` AS `vm_type`, + `user_vm`.`display_name` AS `vm_display_name`, + `volume_store_ref`.`size` AS `volume_store_size`, + `volume_store_ref`.`download_pct` AS `download_pct`, + `volume_store_ref`.`download_state` AS `download_state`, + `volume_store_ref`.`error_str` AS `error_str`, + `volume_store_ref`.`created` AS `created_on_store`, + `disk_offering`.`id` AS `disk_offering_id`, + `disk_offering`.`uuid` AS `disk_offering_uuid`, + `disk_offering`.`name` AS `disk_offering_name`, + `disk_offering`.`display_text` AS `disk_offering_display_text`, + `disk_offering`.`use_local_storage` AS `use_local_storage`, + `disk_offering`.`system_use` AS `system_use`, + `disk_offering`.`bytes_read_rate` AS `bytes_read_rate`, + `disk_offering`.`bytes_write_rate` AS `bytes_write_rate`, + `disk_offering`.`iops_read_rate` AS `iops_read_rate`, + `disk_offering`.`iops_write_rate` AS `iops_write_rate`, + `disk_offering`.`cache_mode` AS `cache_mode`, + `storage_pool`.`id` AS `pool_id`, + `storage_pool`.`uuid` AS `pool_uuid`, + `storage_pool`.`name` AS `pool_name`, + `cluster`.`hypervisor_type` AS `hypervisor_type`, + `vm_template`.`id` AS `template_id`, + `vm_template`.`uuid` AS `template_uuid`, + `vm_template`.`extractable` AS `extractable`, + `vm_template`.`type` AS `template_type`, + `vm_template`.`name` AS `template_name`, + `vm_template`.`display_text` AS `template_display_text`, + `iso`.`id` AS `iso_id`, + `iso`.`uuid` AS `iso_uuid`, + `iso`.`name` AS `iso_name`, + `iso`.`display_text` AS `iso_display_text`, + `resource_tags`.`id` AS `tag_id`, + `resource_tags`.`uuid` AS `tag_uuid`, + `resource_tags`.`key` AS `tag_key`, + `resource_tags`.`value` AS `tag_value`, + `resource_tags`.`domain_id` AS `tag_domain_id`, + `domain`.`uuid` AS `tag_domain_uuid`, + `domain`.`name` AS `tag_domain_name`, + `resource_tags`.`account_id` AS `tag_account_id`, + `account`.`account_name` AS `tag_account_name`, + `resource_tags`.`resource_id` AS `tag_resource_id`, + `resource_tags`.`resource_uuid` AS `tag_resource_uuid`, + `resource_tags`.`resource_type` AS `tag_resource_type`, + `resource_tags`.`customer` AS `tag_customer`, + `async_job`.`id` AS `job_id`, + `async_job`.`uuid` AS `job_uuid`, + `async_job`.`job_status` AS `job_status`, + `async_job`.`account_id` AS `job_account_id` + FROM + ((((((((((((((`volumes` + JOIN `account` ON ((`volumes`.`account_id` = `account`.`id`))) + JOIN `domain` ON ((`volumes`.`domain_id` = `domain`.`id`))) + LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`))) + LEFT JOIN `data_center` ON ((`volumes`.`data_center_id` = `data_center`.`id`))) + LEFT JOIN `vm_instance` ON ((`volumes`.`instance_id` = `vm_instance`.`id`))) + LEFT JOIN `user_vm` ON ((`user_vm`.`id` = `vm_instance`.`id`))) + LEFT JOIN `volume_store_ref` ON ((`volumes`.`id` = `volume_store_ref`.`volume_id`))) + LEFT JOIN `disk_offering` ON ((`volumes`.`disk_offering_id` = `disk_offering`.`id`))) + LEFT JOIN `storage_pool` ON ((`volumes`.`pool_id` = `storage_pool`.`id`))) + LEFT JOIN `cluster` ON ((`storage_pool`.`cluster_id` = `cluster`.`id`))) + LEFT JOIN `vm_template` ON ((`volumes`.`template_id` = `vm_template`.`id`))) + LEFT JOIN `vm_template` `iso` ON ((`iso`.`id` = `volumes`.`iso_id`))) + LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `volumes`.`id`) + AND (`resource_tags`.`resource_type` = 'Volume')))) + LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `volumes`.`id`) + AND (`async_job`.`instance_type` = 'Volume') + AND (`async_job`.`job_status` = 0)))); + +DROP VIEW IF EXISTS `cloud`.`user_vm__view`; + +CREATE + ALGORITHM = UNDEFINED + DEFINER = `cloud`@`%` + SQL SECURITY DEFINER +VIEW `user_vm_view` AS + SELECT + `vm_instance`.`id` AS `id`, + `vm_instance`.`name` AS `name`, + `user_vm`.`display_name` AS `display_name`, + `user_vm`.`user_data` AS `user_data`, + `account`.`id` AS `account_id`, + `account`.`uuid` AS `account_uuid`, + `account`.`account_name` AS `account_name`, + `account`.`type` AS `account_type`, + `domain`.`id` AS `domain_id`, + `domain`.`uuid` AS `domain_uuid`, + `domain`.`name` AS `domain_name`, + `domain`.`path` AS `domain_path`, + `projects`.`id` AS `project_id`, + `projects`.`uuid` AS `project_uuid`, + `projects`.`name` AS `project_name`, + `instance_group`.`id` AS `instance_group_id`, + `instance_group`.`uuid` AS `instance_group_uuid`, + `instance_group`.`name` AS `instance_group_name`, + `vm_instance`.`uuid` AS `uuid`, + `vm_instance`.`user_id` AS `user_id`, + `vm_instance`.`last_host_id` AS `last_host_id`, + `vm_instance`.`vm_type` AS `type`, + `vm_instance`.`limit_cpu_use` AS `limit_cpu_use`, + `vm_instance`.`created` AS `created`, + `vm_instance`.`state` AS `state`, + `vm_instance`.`removed` AS `removed`, + `vm_instance`.`ha_enabled` AS `ha_enabled`, + `vm_instance`.`hypervisor_type` AS `hypervisor_type`, + `vm_instance`.`instance_name` AS `instance_name`, + `vm_instance`.`guest_os_id` AS `guest_os_id`, + `vm_instance`.`display_vm` AS `display_vm`, + `guest_os`.`uuid` AS `guest_os_uuid`, + `vm_instance`.`pod_id` AS `pod_id`, + `host_pod_ref`.`uuid` AS `pod_uuid`, + `vm_instance`.`private_ip_address` AS `private_ip_address`, + `vm_instance`.`private_mac_address` AS `private_mac_address`, + `vm_instance`.`vm_type` AS `vm_type`, + `data_center`.`id` AS `data_center_id`, + `data_center`.`uuid` AS `data_center_uuid`, + `data_center`.`name` AS `data_center_name`, + `data_center`.`is_security_group_enabled` AS `security_group_enabled`, + `data_center`.`networktype` AS `data_center_type`, + `host`.`id` AS `host_id`, + `host`.`uuid` AS `host_uuid`, + `host`.`name` AS `host_name`, + `vm_template`.`id` AS `template_id`, + `vm_template`.`uuid` AS `template_uuid`, + `vm_template`.`name` AS `template_name`, + `vm_template`.`display_text` AS `template_display_text`, + `vm_template`.`enable_password` AS `password_enabled`, + `iso`.`id` AS `iso_id`, + `iso`.`uuid` AS `iso_uuid`, + `iso`.`name` AS `iso_name`, + `iso`.`display_text` AS `iso_display_text`, + `service_offering`.`id` AS `service_offering_id`, + `svc_disk_offering`.`uuid` AS `service_offering_uuid`, + `disk_offering`.`uuid` AS `disk_offering_uuid`, + `disk_offering`.`id` AS `disk_offering_id`, + (CASE + WHEN ISNULL(`service_offering`.`cpu`) THEN `custom_cpu`.`value` + ELSE `service_offering`.`cpu` + END) AS `cpu`, + (CASE + WHEN ISNULL(`service_offering`.`speed`) THEN `custom_speed`.`value` + ELSE `service_offering`.`speed` + END) AS `speed`, + (CASE + WHEN ISNULL(`service_offering`.`ram_size`) THEN `custom_ram_size`.`value` + ELSE `service_offering`.`ram_size` + END) AS `ram_size`, + `svc_disk_offering`.`name` AS `service_offering_name`, + `disk_offering`.`name` AS `disk_offering_name`, + `storage_pool`.`id` AS `pool_id`, + `storage_pool`.`uuid` AS `pool_uuid`, + `storage_pool`.`pool_type` AS `pool_type`, + `volumes`.`id` AS `volume_id`, + `volumes`.`uuid` AS `volume_uuid`, + `volumes`.`device_id` AS `volume_device_id`, + `volumes`.`volume_type` AS `volume_type`, + `security_group`.`id` AS `security_group_id`, + `security_group`.`uuid` AS `security_group_uuid`, + `security_group`.`name` AS `security_group_name`, + `security_group`.`description` AS `security_group_description`, + `nics`.`id` AS `nic_id`, + `nics`.`uuid` AS `nic_uuid`, + `nics`.`network_id` AS `network_id`, + `nics`.`ip4_address` AS `ip_address`, + `nics`.`ip6_address` AS `ip6_address`, + `nics`.`ip6_gateway` AS `ip6_gateway`, + `nics`.`ip6_cidr` AS `ip6_cidr`, + `nics`.`default_nic` AS `is_default_nic`, + `nics`.`gateway` AS `gateway`, + `nics`.`netmask` AS `netmask`, + `nics`.`mac_address` AS `mac_address`, + `nics`.`broadcast_uri` AS `broadcast_uri`, + `nics`.`isolation_uri` AS `isolation_uri`, + `vpc`.`id` AS `vpc_id`, + `vpc`.`uuid` AS `vpc_uuid`, + `networks`.`uuid` AS `network_uuid`, + `networks`.`name` AS `network_name`, + `networks`.`traffic_type` AS `traffic_type`, + `networks`.`guest_type` AS `guest_type`, + `user_ip_address`.`id` AS `public_ip_id`, + `user_ip_address`.`uuid` AS `public_ip_uuid`, + `user_ip_address`.`public_ip_address` AS `public_ip_address`, + `ssh_keypairs`.`keypair_name` AS `keypair_name`, + `resource_tags`.`id` AS `tag_id`, + `resource_tags`.`uuid` AS `tag_uuid`, + `resource_tags`.`key` AS `tag_key`, + `resource_tags`.`value` AS `tag_value`, + `resource_tags`.`domain_id` AS `tag_domain_id`, + `domain`.`uuid` AS `tag_domain_uuid`, + `domain`.`name` AS `tag_domain_name`, + `resource_tags`.`account_id` AS `tag_account_id`, + `account`.`account_name` AS `tag_account_name`, + `resource_tags`.`resource_id` AS `tag_resource_id`, + `resource_tags`.`resource_uuid` AS `tag_resource_uuid`, + `resource_tags`.`resource_type` AS `tag_resource_type`, + `resource_tags`.`customer` AS `tag_customer`, + `async_job`.`id` AS `job_id`, + `async_job`.`uuid` AS `job_uuid`, + `async_job`.`job_status` AS `job_status`, + `async_job`.`account_id` AS `job_account_id`, + `affinity_group`.`id` AS `affinity_group_id`, + `affinity_group`.`uuid` AS `affinity_group_uuid`, + `affinity_group`.`name` AS `affinity_group_name`, + `affinity_group`.`description` AS `affinity_group_description`, + `vm_instance`.`dynamically_scalable` AS `dynamically_scalable` + FROM + ((((((((((((((((((((((((((((((((`user_vm` + JOIN `vm_instance` ON (((`vm_instance`.`id` = `user_vm`.`id`) + AND ISNULL(`vm_instance`.`removed`)))) + JOIN `account` ON ((`vm_instance`.`account_id` = `account`.`id`))) + JOIN `domain` ON ((`vm_instance`.`domain_id` = `domain`.`id`))) + LEFT JOIN `guest_os` ON ((`vm_instance`.`guest_os_id` = `guest_os`.`id`))) + LEFT JOIN `host_pod_ref` ON ((`vm_instance`.`pod_id` = `host_pod_ref`.`id`))) + LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`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 `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` `svc_disk_offering` ON ((`vm_instance`.`service_offering_id` = `svc_disk_offering`.`id`))) + LEFT JOIN `disk_offering` ON ((`vm_instance`.`disk_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`) + AND ISNULL(`nics`.`removed`)))) + LEFT JOIN `networks` ON ((`nics`.`network_id` = `networks`.`id`))) + LEFT JOIN `vpc` ON (((`networks`.`vpc_id` = `vpc`.`id`) + AND ISNULL(`vpc`.`removed`)))) + LEFT JOIN `user_ip_address` ON ((`user_ip_address`.`vm_id` = `vm_instance`.`id`))) + LEFT JOIN `user_vm_details` `ssh_details` ON (((`ssh_details`.`vm_id` = `vm_instance`.`id`) + AND (`ssh_details`.`name` = 'SSH.PublicKey')))) + LEFT JOIN `ssh_keypairs` ON (((`ssh_keypairs`.`public_key` = `ssh_details`.`value`) + AND (`ssh_keypairs`.`account_id` = `account`.`id`)))) + LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_instance`.`id`) + AND (`resource_tags`.`resource_type` = 'UserVm')))) + LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `vm_instance`.`id`) + AND (`async_job`.`instance_type` = 'VirtualMachine') + AND (`async_job`.`job_status` = 0)))) + LEFT JOIN `affinity_group_vm_map` ON ((`vm_instance`.`id` = `affinity_group_vm_map`.`instance_id`))) + LEFT JOIN `affinity_group` ON ((`affinity_group_vm_map`.`affinity_group_id` = `affinity_group`.`id`))) + LEFT JOIN `user_vm_details` `custom_cpu` ON (((`custom_cpu`.`vm_id` = `vm_instance`.`id`) + AND (`custom_cpu`.`name` = 'CpuNumber')))) + LEFT JOIN `user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `vm_instance`.`id`) + AND (`custom_speed`.`name` = 'CpuSpeed')))) + LEFT JOIN `user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `vm_instance`.`id`) + AND (`custom_ram_size`.`name` = 'memory'))));