Merge pull request #1425 from nvazquez/listtemplates

CLOUDSTACK-9298: Improve performance of resource retrieval that have tags associated and target volumes, VMs and templatesJIRA TICKET: https://issues.apache.org/jira/browse/CLOUDSTACK-9298

## Description of the problem
When retrieving a large number of resources which have tags associated with, retrieval methods took too long. Our goal is to improve performance of this methods avoiding query the database for each tag, managing that information in memory.
API methods to improve: <code>listTemplates</code>, <code>listVolumes</code>, <code>listVirtualMachines</code>

To achive it, it's necessary to include new columns in <code>template_view</code>, <code>volume_view</code> and <code>user_vm_view</code>:
* tag_account_name
* tag_domain_name
* tag_domain_uuid

* pr/1425:
  CLOUDSTACK-9298: Remove user definer from view creations
  CLOUDSTACK-9298: Add @MappedSuperClass support for persistence inheritance
  CLOUDSTACK-9298: Improve ListTemplatesCmd, ListVolumesCmd and ListVMsCmd performance

Signed-off-by: Will Stevens <williamstevens@gmail.com>
This commit is contained in:
Will Stevens 2016-03-31 22:24:36 -04:00
commit 419f8fba63
20 changed files with 1003 additions and 315 deletions

View File

@ -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<ResourceTagResponse> tags;
public void addTag(ResourceTagResponse tag) {
this.tags.add(tag);
}
public Set<ResourceTagResponse> getTags(){
return this.tags;
}
}

View File

@ -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;

View File

@ -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<TemplateZoneResponse> zones;
@SerializedName(ApiConstants.TAGS)
@Param(description = "the list of resource tags associated with tempate", responseObject = ResourceTagResponse.class)
private Set<ResourceTagResponse> 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;
}
}

View File

@ -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<ResourceTagResponse> tags;
transient Set<Long> tagIds;
@SerializedName(ApiConstants.DETAILS)
@ -514,10 +510,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
return instanceName;
}
public Set<ResourceTagResponse> 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;
}

View File

@ -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<ResourceTagResponse> 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<ResourceTagResponse> 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<ResourceTagResponse> tags) {
this.tags = tags;
}
}

View File

@ -38,10 +38,12 @@ import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.TableGenerator;
import org.apache.commons.lang.ArrayUtils;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.db.Attribute.Flag;
@ -54,6 +56,7 @@ public class SqlGenerator {
LinkedHashMap<String, List<Attribute>> _ids;
HashMap<String, TableGenerator> _generators;
ArrayList<Attribute> _ecAttrs;
Field[] _mappedSuperclassFields;
public SqlGenerator(Class<?> clazz) {
_clazz = clazz;
@ -91,6 +94,12 @@ public class SqlGenerator {
protected void buildAttributes(Class<?> clazz, String tableName, AttributeOverride[] overrides, boolean embedded, boolean isId) {
if (!embedded && clazz.getAnnotation(Entity.class) == null) {
// A class designated with the MappedSuperclass annotation can be mapped in the same way as an entity
// except that the mappings will apply only to its subclasses since no table exists for the mapped superclass itself
if (clazz.getAnnotation(MappedSuperclass.class) != null){
Field[] declaredFields = clazz.getDeclaredFields();
_mappedSuperclassFields = (Field[]) ArrayUtils.addAll(_mappedSuperclassFields, declaredFields);
}
return;
}
@ -105,6 +114,8 @@ public class SqlGenerator {
}
Field[] fields = clazz.getDeclaredFields();
fields = (Field[]) ArrayUtils.addAll(fields, _mappedSuperclassFields);
_mappedSuperclassFields = null;
for (Field field : fields) {
field.setAccessible(true);

View File

@ -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<T extends BaseViewWithTagInformationVO, Z extends BaseResponseWithTagInformation> extends GenericDaoBase<T, Long> {
/**
* 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));
}
}

View File

@ -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<TemplateJoinVO, Long> implements TemplateJoinDao {
public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<TemplateJoinVO, TemplateResponse> implements TemplateJoinDao {
public static final Logger s_logger = Logger.getLogger(TemplateJoinDaoImpl.class);
@ -188,10 +187,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> 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<TemplateJoinVO, Long> 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;

View File

@ -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<UserVmJoinVO, Long> implements UserVmJoinDao {
public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJoinVO, UserVmResponse> implements UserVmJoinDao {
public static final Logger s_logger = Logger.getLogger(UserVmJoinDaoImpl.class);
@Inject
@ -283,10 +281,7 @@ public class UserVmJoinDaoImpl extends GenericDaoBase<UserVmJoinVO, Long> 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<UserVmJoinVO, Long> 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();

View File

@ -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<VolumeJoinVO, Long> implements VolumeJoinDao {
public class VolumeJoinDaoImpl extends GenericDaoBaseWithTagInformation<VolumeJoinVO, VolumeResponse> implements VolumeJoinDao {
public static final Logger s_logger = Logger.getLogger(VolumeJoinDaoImpl.class);
@Inject
@ -221,10 +219,7 @@ public class VolumeJoinDaoImpl extends GenericDaoBase<VolumeJoinVO, Long> 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<VolumeJoinVO, Long> 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;
}

View File

@ -0,0 +1,183 @@
// 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 java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import com.cloud.server.ResourceTag.ResourceObjectType;
@MappedSuperclass
public abstract class BaseViewWithTagInformationVO extends BaseViewVO implements Serializable {
@Id
@Column(name = "id")
private long id;
@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;
}
public long getId() {
return id;
}
}

View File

@ -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;
}
}

View File

@ -22,7 +22,6 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@ -30,7 +29,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,11 +38,7 @@ import com.cloud.utils.db.GenericDao;
@Entity
@Table(name = "template_view")
public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity {
@Id
@Column(name = "id")
private long id;
public class TemplateJoinVO extends BaseViewWithTagInformationVO implements ControlledViewEntity {
@Column(name = "uuid")
private String uuid;
@ -218,37 +212,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;
@ -259,11 +222,6 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity {
public TemplateJoinVO() {
}
@Override
public long getId() {
return id;
}
@Override
public String getUuid() {
return uuid;
@ -343,46 +301,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 +465,9 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity {
public Class<?> getEntityType() {
return VirtualMachineTemplate.class;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
}

View File

@ -20,6 +20,7 @@ import java.net.URI;
import java.util.Date;
import java.util.Map;
import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
@ -31,7 +32,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 +40,8 @@ import com.cloud.vm.VirtualMachine.State;
@Entity
@Table(name = "user_vm_view")
public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity {
@AttributeOverride( name="id", column = @Column(name = "id", updatable = false, nullable = false) )
public class UserVmJoinVO extends BaseViewWithTagInformationVO implements ControlledViewEntity {
@Id
@Column(name = "id", updatable = false, nullable = false)
@ -346,37 +347,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;
@ -404,11 +374,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity {
public UserVmJoinVO() {
}
@Override
public long getId() {
return id;
}
@Override
public String getUuid() {
return uuid;
@ -776,46 +741,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;
}
@ -865,7 +790,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity {
@Override
public String toString() {
if (toString == null) {
toString = new StringBuilder("VM[").append(id).append("|").append(name).append("]").toString();
toString = new StringBuilder("VM[").append(getId()).append("|").append(name).append("]").toString();
}
return toString;
}
@ -907,4 +832,5 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity {
public Class<?> getEntityType() {
return VirtualMachine.class;
}
}

View File

@ -22,13 +22,11 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.Table;
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,11 +35,7 @@ import com.cloud.vm.VirtualMachine;
@Entity
@Table(name = "volume_view")
public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
@Id
@Column(name = "id")
private long id;
public class VolumeJoinVO extends BaseViewWithTagInformationVO implements ControlledViewEntity {
@Column(name = "uuid")
private String uuid;
@ -252,37 +246,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;
@ -295,11 +258,6 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
public VolumeJoinVO() {
}
@Override
public long getId() {
return id;
}
@Override
public String getUuid() {
return uuid;
@ -563,46 +521,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 +554,5 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
public Class<?> getEntityType() {
return Volume.class;
}
}

View File

@ -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<T extends BaseViewWithTagInformationVO,
Z extends BaseResponseWithTagInformation> {
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<T, Z> 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());
}
}

View File

@ -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<TemplateJoinVO, TemplateResponse> {
@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);
}
}

View File

@ -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<UserVmJoinVO, UserVmResponse> {
@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);
}
}

View File

@ -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<VolumeJoinVO, VolumeResponse> {
@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);
}
}

View File

@ -21,3 +21,392 @@
ALTER TABLE `event` ADD INDEX `archived` (`archived`);
ALTER TABLE `event` ADD INDEX `state` (`state`);
DROP VIEW IF EXISTS `cloud`.`template_view`;
CREATE
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
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
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'))));