/**
* Abiquo community edition
* cloud management application for hybrid clouds
* Copyright (C) 2008-2010 - Abiquo Holdings S.L.
*
* This application is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC
* LICENSE as published by the Free Software Foundation under
* version 3 of the License
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* LESSER GENERAL PUBLIC LICENSE v.3 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package com.abiquo.server.core.appslibrary;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import com.abiquo.model.enumerator.DiskFormatType;
import com.abiquo.model.enumerator.EthernetDriverType;
import com.abiquo.server.core.common.DefaultEntityBase;
import com.abiquo.server.core.enterprise.Enterprise;
import com.abiquo.server.core.infrastructure.DatacenterDto;
import com.abiquo.server.core.infrastructure.Repository;
import com.abiquo.server.core.infrastructure.storage.VolumeManagement;
import com.softwarementors.validation.constraints.LeadingOrTrailingWhitespace;
import com.softwarementors.validation.constraints.Required;
@Entity
@Table(name = VirtualMachineTemplate.TABLE_NAME)
@org.hibernate.annotations.Table(appliesTo = VirtualMachineTemplate.TABLE_NAME)
public class VirtualMachineTemplate extends DefaultEntityBase
{
public static final String TABLE_NAME = "virtualimage";
// DO NOT ACCESS: present due to needs of infrastructure support. *NEVER* call from business
// code
public VirtualMachineTemplate()
{
// Just for JPA support
}
public VirtualMachineTemplate(final Enterprise enterprise, final String name,
final DiskFormatType diskFormatType, final String path, final long diskFileSize,
final Category category, final String creationUser)
{
super();
this.enterprise = enterprise;
this.name = name;
this.diskFormatType = diskFormatType;
this.path = path;
this.diskFileSize = diskFileSize;
this.category = category;
this.creationUser = creationUser;
}
public VirtualMachineTemplate(final Enterprise enterprise, final String name,
final DiskFormatType diskFormatType, final String path, final long diskFileSize,
final Category category, final String creationUser, final VolumeManagement volume)
{
super();
this.enterprise = enterprise;
this.name = name;
this.diskFormatType = diskFormatType;
this.path = path;
this.diskFileSize = diskFileSize;
this.category = category;
this.volume = volume;
this.stateful = volume != null;
this.creationUser = creationUser;
}
public final static String ID_COLUMN = "idImage";
@Id
@GeneratedValue
@Column(name = ID_COLUMN, nullable = false)
private Integer id;
@Override
public Integer getId()
{
return this.id;
}
public void setId(final Integer id)
{
this.id = id;
}
public final static String DISKFORMAT_TYPE_PROPERTY = "diskFormatType";
private final static boolean DISKFORMAT_TYPE_REQUIRED = true;
private final static String DISKFORMAT_TYPE_COLUMN = "type";
private final static int DISKFORMAT_TYPE_COLUMN_LENGTH = 50;
@Enumerated(value = javax.persistence.EnumType.STRING)
@Column(name = DISKFORMAT_TYPE_COLUMN, nullable = !DISKFORMAT_TYPE_REQUIRED, length = DISKFORMAT_TYPE_COLUMN_LENGTH)
private DiskFormatType diskFormatType;
@Required(value = DISKFORMAT_TYPE_REQUIRED)
public DiskFormatType getDiskFormatType()
{
return this.diskFormatType;
}
public void setDiskFormatType(final DiskFormatType diskFormatType)
{
this.diskFormatType = diskFormatType;
}
public final static String NAME_PROPERTY = "name";
private final static boolean NAME_REQUIRED = true;
/* package */final static int NAME_LENGTH_MIN = 0;
/* package */final static int NAME_LENGTH_MAX = 255;
private final static boolean NAME_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false;
private final static String NAME_COLUMN = "name";
@Column(name = NAME_COLUMN, nullable = !NAME_REQUIRED, length = NAME_LENGTH_MAX)
private String name;
@Required(value = NAME_REQUIRED)
@Length(min = NAME_LENGTH_MIN, max = NAME_LENGTH_MAX)
@LeadingOrTrailingWhitespace(allowed = NAME_LEADING_OR_TRAILING_WHITESPACES_ALLOWED)
public String getName()
{
return this.name;
}
public void setName(final String name)
{
this.name = name;
}
public final static String STATEFUL_PROPERTY = "stateful";
private final static String STATEFUL_COLUMN = "stateful";
private final static boolean STATEFUL_REQUIRED = true;
@Column(name = STATEFUL_COLUMN, columnDefinition = "int", nullable = false)
private boolean stateful = false;
@Required(value = STATEFUL_REQUIRED)
public boolean isStateful()
{
return this.stateful; // && getVolume() != null;
}
/**
* This method should be only called from VolumeManagement.setVirtualMachineTemplate()
*/
public void setStateful(final boolean stateful)
{
this.stateful = stateful;
}
public final static String VOLUME_PROPERTY = "volume";
private final static boolean VOLUME_REQUIRED = false;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "virtualMachineTemplate")
private VolumeManagement volume;
@Required(value = VOLUME_REQUIRED)
public VolumeManagement getVolume()
{
return volume;
}
// Set volume is not available. The link to the volume must be performed by calling
// VolumeManagement.setVirtualMachineTemplate
public final static String SHARED_PROPERTY = "shared";
private final static String SHARED_COLUMN = "shared";
private final static boolean SHARED_REQUIRED = true;
@Column(name = SHARED_COLUMN, columnDefinition = "int", nullable = false)
private boolean shared = false;
@Required(value = SHARED_REQUIRED)
public boolean isShared()
{
return this.shared;
}
public void setShared(final boolean shared)
{
this.shared = shared;
}
public final static String CPU_REQUIRED_PROPERTY = "cpuRequired";
private final static String CPU_REQUIRED_COLUMN = "cpu_required";
private final static int CPU_REQUIRED_MIN = Integer.MIN_VALUE;
private final static int CPU_REQUIRED_MAX = Integer.MAX_VALUE;
@Column(name = CPU_REQUIRED_COLUMN, nullable = true)
@Range(min = CPU_REQUIRED_MIN, max = CPU_REQUIRED_MAX)
private int cpuRequired;
public int getCpuRequired()
{
return this.cpuRequired;
}
public void setCpuRequired(final int cpuRequired)
{
this.cpuRequired = cpuRequired;
}
public final static String ENTERPRISE_PROPERTY = "enterprise";
private final static boolean ENTERPRISE_REQUIRED = true;
private final static String ENTERPRISE_ID_COLUMN = "idEnterprise";
@JoinColumn(name = ENTERPRISE_ID_COLUMN)
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "FK_" + TABLE_NAME + "_enterprise")
private Enterprise enterprise;
@Required(value = ENTERPRISE_REQUIRED)
public Enterprise getEnterprise()
{
return this.enterprise;
}
public void setEnterprise(final Enterprise enterprise)
{
this.enterprise = enterprise;
}
public final static String PATH_PROPERTY = "path";
private final static boolean PATH_REQUIRED = true;
/* package */final static int PATH_LENGTH_MIN = 0;
/* package */final static int PATH_LENGTH_MAX = 255;
private final static boolean PATH_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false;
private final static String PATH_COLUMN = "pathName";
@Column(name = PATH_COLUMN, nullable = !PATH_REQUIRED, length = PATH_LENGTH_MAX)
private String path;
@Required(value = PATH_REQUIRED)
@Length(min = PATH_LENGTH_MIN, max = PATH_LENGTH_MAX)
@LeadingOrTrailingWhitespace(allowed = PATH_LEADING_OR_TRAILING_WHITESPACES_ALLOWED)
public String getPath()
{
return this.path;
}
public void setPath(final String path)
{
this.path = path;
}
public final static String OVFID_PROPERTY = "ovfid";
final static boolean OVFID_REQUIRED = false;
/* package */final static int OVFID_LENGTH_MIN = 0;
/* package */final static int OVFID_LENGTH_MAX = 255;
final static boolean OVFID_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false;
private final static String OVFID_COLUMN = "ovfid";
@Column(name = OVFID_COLUMN, nullable = !OVFID_REQUIRED, length = OVFID_LENGTH_MAX)
private String ovfid;
@Required(value = OVFID_REQUIRED)
@Length(min = OVFID_LENGTH_MIN, max = OVFID_LENGTH_MAX)
@LeadingOrTrailingWhitespace(allowed = OVFID_LEADING_OR_TRAILING_WHITESPACES_ALLOWED)
public String getOvfid()
{
return this.ovfid;
}
public void setOvfid(final String ovfid)
{
this.ovfid = ovfid;
}
public final static String RAM_REQUIRED_PROPERTY = "ramRequired";
private final static String RAM_REQUIRED_COLUMN = "ram_required";
private final static int RAM_REQUIRED_MIN = Integer.MIN_VALUE;
private final static int RAM_REQUIRED_MAX = Integer.MAX_VALUE;
@Column(name = RAM_REQUIRED_COLUMN, nullable = true)
@Range(min = RAM_REQUIRED_MIN, max = RAM_REQUIRED_MAX)
private int ramRequired;
public int getRamRequired()
{
return this.ramRequired;
}
public void setRamRequired(final int ramRequired)
{
this.ramRequired = ramRequired;
}
public final static String HD_REQUIRED_PROPERTY = "hdRequiredInBytes";
private final static String HD_REQUIRED_COLUMN = "hd_required";
private final static long HD_REQUIRED_MIN = Long.MIN_VALUE;
private final static long HD_REQUIRED_MAX = Long.MAX_VALUE;
@Column(name = HD_REQUIRED_COLUMN, nullable = true)
@Range(min = HD_REQUIRED_MIN, max = HD_REQUIRED_MAX)
private long hdRequiredInBytes;
public long getHdRequiredInBytes()
{
return this.hdRequiredInBytes;
}
public void setHdRequiredInBytes(final long hdRequiredInBytes)
{
this.hdRequiredInBytes = hdRequiredInBytes;
}
public final static String MASTER_PROPERTY = "master";
private final static boolean MASTER_REQUIRED = false;
private final static String MASTER_ID_COLUMN = "idMaster";
@JoinColumn(name = MASTER_ID_COLUMN)
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "FK_" + TABLE_NAME + "_master")
private VirtualMachineTemplate master;
@Required(value = MASTER_REQUIRED)
public VirtualMachineTemplate getMaster()
{
return this.master;
}
public void setMaster(final VirtualMachineTemplate master)
{
this.master = master;
}
public final static String CATEGORY_PROPERTY = "category";
private final static boolean CATEGORY_REQUIRED = true;
private final static String CATEGORY_ID_COLUMN = "idCategory";
@JoinColumn(name = CATEGORY_ID_COLUMN)
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "FK_" + TABLE_NAME + "_category")
private Category category;
@Required(value = CATEGORY_REQUIRED)
public Category getCategory()
{
return this.category;
}
public void setCategory(final Category category)
{
this.category = category;
}
public final static String DISK_FILE_SIZE_PROPERTY = "diskFileSize";
private final static String DISK_FILE_SIZE_COLUMN = "diskFileSize";
private final static long DISK_FILE_SIZE_MIN = Long.MIN_VALUE;
private final static long DISK_FILE_SIZE_MAX = Long.MAX_VALUE;
@Column(name = DISK_FILE_SIZE_COLUMN, nullable = false)
@Range(min = DISK_FILE_SIZE_MIN, max = DISK_FILE_SIZE_MAX)
private long diskFileSize;
public long getDiskFileSize()
{
return this.diskFileSize;
}
public void setDiskFileSize(final long diskFileSize)
{
this.diskFileSize = diskFileSize;
}
public final static String DESCRIPTION_PROPERTY = "description";
private final static boolean DESCRIPTION_REQUIRED = false;
private final static int DESCRIPTION_LENGTH_MIN = 0;
private final static int DESCRIPTION_LENGTH_MAX = 255;
private final static boolean DESCRIPTION_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = true;
private final static String DESCRIPTION_COLUMN = "description";
@Column(name = DESCRIPTION_COLUMN, nullable = !DESCRIPTION_REQUIRED, length = DESCRIPTION_LENGTH_MAX)
private String description;
@Required(value = DESCRIPTION_REQUIRED)
@Length(min = DESCRIPTION_LENGTH_MIN, max = DESCRIPTION_LENGTH_MAX)
@LeadingOrTrailingWhitespace(allowed = DESCRIPTION_LEADING_OR_TRAILING_WHITESPACES_ALLOWED)
public String getDescription()
{
return this.description;
}
public void setDescription(final String description)
{
this.description = description;
}
public final static String ICON_URL_PROPERTY = "iconUrl";
private final static boolean ICON_URL_REQUIRED = false;
private final static int ICON_URL_LENGTH_MIN = 0;
private final static int ICON_URL_LENGTH_MAX = 255;
private final static boolean ICON_URL_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false;
private final static String ICON_URL_COLUMN = "iconUrl";
@Column(name = ICON_URL_COLUMN, nullable = !ICON_URL_REQUIRED, length = ICON_URL_LENGTH_MAX)
private String iconUrl;
@Required(value = ICON_URL_REQUIRED)
@Length(min = ICON_URL_LENGTH_MIN, max = ICON_URL_LENGTH_MAX)
@LeadingOrTrailingWhitespace(allowed = ICON_URL_LEADING_OR_TRAILING_WHITESPACES_ALLOWED)
public String getIconUrl()
{
return this.iconUrl;
}
public void setIconUrl(final String iconUrl)
{
this.iconUrl = iconUrl;
}
public final static String COST_CODE_PROPERTY = "costCode";
private final static boolean COST_CODE_REQUIRED = false;
private final static int COST_CODE_LENGTH_MIN = 0;
private final static int COST_CODE_LENGTH_MAX = 50;
private final static String COST_CODE_COLUMN = "cost_code";
@Column(name = COST_CODE_COLUMN, nullable = !COST_CODE_REQUIRED)
private int costCode;
@Required(value = COST_CODE_REQUIRED)
public int getCostCode()
{
return costCode;
}
public void setCostCode(final int costCode)
{
this.costCode = costCode;
}
public final static String REPOSITORY_PROPERTY = "repository";
private final static boolean REPOSITORY_REQUIRED = false;
private final static String REPOSITORY_ID_COLUMN = "idRepository";
@JoinColumn(name = REPOSITORY_ID_COLUMN)
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "FK_" + TABLE_NAME + "_repository")
private Repository repository;
@Required(value = REPOSITORY_REQUIRED)
public Repository getRepository()
{
return repository;
}
public void setRepository(final Repository repository)
{
this.repository = repository;
}
public final static String CHEF_PROPERTY = "chefEnabled";
public final static String CHEF_COLUMN = "chefEnabled";
private final static boolean CHEF_REQUIRED = true;
@Column(name = CHEF_COLUMN, nullable = false)
private boolean chefEnabled = false;
@Required(value = CHEF_REQUIRED)
public boolean isChefEnabled()
{
return chefEnabled;
}
public void setChefEnabled(final boolean chefEnabled)
{
this.chefEnabled = chefEnabled;
}
public final static String CREATION_DATE_PROPERTY = "creationDate";
private final static boolean CREATION_DATE_REQUIRED = false;
private final static String CREATION_DATE_COLUMN = "creation_date";
@Column(name = CREATION_DATE_COLUMN, nullable = !CREATION_DATE_REQUIRED)
private Date creationDate;
@Required(value = CREATION_DATE_REQUIRED)
public Date getCreationDate()
{
return creationDate;
}
public final static String CREATION_USER_PROPERTY = "creationUser";
private final static boolean CREATION_USER_REQUIRED = true;
/* package */final static int CREATION_USER_LENGTH_MIN = 0;
/* package */final static int CREATION_USER_LENGTH_MAX = 128;
private final static boolean CREATION_USER_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false;
private final static String CREATION_USER_COLUMN = "creation_user";
@Column(name = CREATION_USER_COLUMN, nullable = !CREATION_USER_REQUIRED, length = CREATION_USER_LENGTH_MAX)
private String creationUser;
@Required(value = CREATION_USER_REQUIRED)
@Length(min = CREATION_USER_LENGTH_MIN, max = CREATION_USER_LENGTH_MAX)
@LeadingOrTrailingWhitespace(allowed = CREATION_USER_LEADING_OR_TRAILING_WHITESPACES_ALLOWED)
public String getCreationUser()
{
return creationUser;
}
public void setCreationUser(final String creationUser)
{
this.creationUser = creationUser;
}
public final static String ETHERNET_DRIVER_TYPE_PROPERTY = "ethernetDriverType";
private final static boolean ETHERNET_DRIVER_TYPE_REQUIRED = false;
private final static String ETHERNET_DRIVER_TYPE_COLUMN = "ethDriverType";
private final static int ETHERNET_DRIVER_TYPE_COLUMN_LENGTH = 16;
@Enumerated(value = javax.persistence.EnumType.STRING)
@Column(name = ETHERNET_DRIVER_TYPE_COLUMN, nullable = !ETHERNET_DRIVER_TYPE_REQUIRED, length = ETHERNET_DRIVER_TYPE_COLUMN_LENGTH)
private EthernetDriverType ethernetDriverType;
@Required(value = ETHERNET_DRIVER_TYPE_REQUIRED)
public EthernetDriverType getEthernetDriverType()
{
return this.ethernetDriverType;
}
public void setEthernetDriverType(final EthernetDriverType ethernetDriverType)
{
this.ethernetDriverType = ethernetDriverType;
}
// Creation date does not have a setter, since it will be auto generated.
/* *********************** Helper methods ************************* */
public void setRequirements(final int cpu, final int ram, final long hd)
{
setCpuRequired(cpu);
setRamRequired(ram);
setHdRequiredInBytes(hd);
}
public boolean isManaged()
{
return getRepository() != null || isStateful();
}
public boolean isMaster()
{
return getMaster() == null;
}
public String getFileRef()
{
return getName() + "." + getId();
}
public String getNotManagedBundlePath()
{
return getEnterprise().getId() + "/bundle/" + getName();
}
public String getNotManagedBundleName()
{
String name = getName() + "-snapshot";
if (isVhd(getPath()))
{
name = vhdPath(name);
}
return name;
}
private boolean isVhd(final String path)
{
return path.endsWith(".vhd");
}
private String vhdPath(final String path)
{
return path + ".vhd";
}
public final static String CONVERSIONS_PROPERTY = "conversions";
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "virtualMachineTemplate")
private final List<VirtualImageConversion> conversions =
new ArrayList<VirtualImageConversion>();
protected void addConversion(final VirtualImageConversion conversion)
{
conversions.add(conversion);
}
}