/** * 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.infrastructure; import java.util.ArrayList; 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.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Transient; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.hibernate.annotations.ForeignKey; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Range; import com.abiquo.model.enumerator.HypervisorType; import com.abiquo.model.enumerator.MachineState; import com.abiquo.server.core.cloud.Hypervisor; import com.abiquo.server.core.common.DefaultEntityBase; import com.abiquo.server.core.enterprise.Enterprise; import com.softwarementors.validation.constraints.LeadingOrTrailingWhitespace; import com.softwarementors.validation.constraints.Required; @Entity @Table(name = Machine.TABLE_NAME, uniqueConstraints = {}) @org.hibernate.annotations.Table(appliesTo = Machine.TABLE_NAME, indexes = {}) public class Machine extends DefaultEntityBase { // ****************************** JPA support // ******************************* public static final String TABLE_NAME = "physicalmachine"; // DO NOT ACCESS: present due to needs of infrastructure support. *NEVER* // call from business code public Machine() { // Just for JPA support } private final static String ID_COLUMN = "idPhysicalMachine"; @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; } // ******************************* Properties // ******************************* public final static String NAME_PROPERTY = "name"; final static boolean NAME_REQUIRED = true; final static int NAME_LENGTH_MIN = 1; final static int NAME_LENGTH_MAX = 128; 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 DESCRIPTION_PROPERTY = "description"; private final static boolean DESCRIPTION_REQUIRED = false; final static int DESCRIPTION_LENGTH_MIN = 0; final static int DESCRIPTION_LENGTH_MAX = 100; private final static boolean DESCRIPTION_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false; 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 VIRTUAL_RAM_IN_MB_PROPERTY = "virtualRamInMb"; /* package */final static String VIRTUAL_RAM_IN_MB_COLUMN = "ram"; /* package */final static int VIRTUAL_RAM_IN_MB_MIN = 0; /* package */final static int VIRTUAL_RAM_IN_MB_MAX = Integer.MAX_VALUE; /* package */final static boolean VIRTUAL_RAM_IN_MB_REQUIRED = true; @Column(name = VIRTUAL_RAM_IN_MB_COLUMN, nullable = false) @Range(min = VIRTUAL_RAM_IN_MB_MIN, max = VIRTUAL_RAM_IN_MB_MAX) private Integer virtualRamInMb; @Required(value = VIRTUAL_RAM_IN_MB_REQUIRED) public Integer getVirtualRamInMb() { return this.virtualRamInMb; } public void setVirtualRamInMb(final Integer virtualRamInMb) { this.virtualRamInMb = virtualRamInMb; } public final static String VIRTUAL_CPU_CORES_PROPERTY = "virtualCpuCores"; /* package */final static String VIRTUAL_CPU_CORES_COLUMN = "cpu"; /* package */final static int VIRTUAL_CPU_CORES_MIN = 0; /* package */final static int VIRTUAL_CPU_CORES_MAX = Integer.MAX_VALUE; /* package */final static boolean VIRTUAL_CPU_CORES_REQUIRED = true; @Column(name = VIRTUAL_CPU_CORES_COLUMN, nullable = false) @Range(min = VIRTUAL_CPU_CORES_MIN, max = VIRTUAL_CPU_CORES_MAX) private Integer virtualCpuCores; @Required(value = VIRTUAL_CPU_CORES_REQUIRED) public Integer getVirtualCpuCores() { return this.virtualCpuCores; } public void setVirtualCpuCores(final Integer virtualCpuCores) { this.virtualCpuCores = virtualCpuCores; } public final static String VIRTUAL_RAM_USED_IN_MB_PROPERTY = "virtualRamUsedInMb"; /* package */final static String VIRTUAL_RAM_USED_IN_MB_COLUMN = "ramUsed"; /* package */final static int VIRTUAL_RAM_USED_IN_MB_MIN = 0; /* package */final static int VIRTUAL_RAM_USED_IN_MB_MAX = Integer.MAX_VALUE; /* package */final static boolean VIRTUAL_RAM_USED_IN_MB_REQUIRED = true; @Column(name = VIRTUAL_RAM_USED_IN_MB_COLUMN, nullable = false) @Range(min = VIRTUAL_RAM_USED_IN_MB_MIN, max = VIRTUAL_RAM_USED_IN_MB_MAX) private Integer virtualRamUsedInMb; @Required(value = VIRTUAL_RAM_USED_IN_MB_REQUIRED) public Integer getVirtualRamUsedInMb() { return this.virtualRamUsedInMb; } public void setVirtualRamUsedInMb(final Integer virtualRamUsedInMb) { this.virtualRamUsedInMb = virtualRamUsedInMb; } public final static String VIRTUAL_CPUS_USED_PROPERTY = "virtualCpusUsed"; /* package */final static String VIRTUAL_CPUS_USED_COLUMN = "cpuUsed"; /* package */final static long VIRTUAL_CPUS_USED_MIN = 0; /* package */final static long VIRTUAL_CPUS_USED_MAX = Integer.MAX_VALUE; /* package */final static boolean VIRTUAL_CPUS_USED_REQUIRED = true; @Column(name = VIRTUAL_CPUS_USED_COLUMN, nullable = false) @Range(min = VIRTUAL_CPUS_USED_MIN, max = VIRTUAL_CPUS_USED_MAX) private Integer virtualCpusUsed; @Required(value = VIRTUAL_CPUS_USED_REQUIRED) public Integer getVirtualCpusUsed() { return this.virtualCpusUsed; } public void setVirtualCpusUsed(final Integer virtualCpusUsed) { this.virtualCpusUsed = virtualCpusUsed; } public final static String STATE_PROPERTY = "state"; private final static boolean STATE_REQUIRED = true; private final static String STATE_COLUMN = "idState"; @Enumerated(value = javax.persistence.EnumType.ORDINAL) @Column(name = STATE_COLUMN, nullable = !STATE_REQUIRED) private MachineState state; @Required(value = STATE_REQUIRED) public MachineState getState() { return this.state; } public void setState(final MachineState state) { this.state = state; } public final static String VIRTUAL_SWITCH_PROPERTY = "virtualSwitch"; public final static boolean VIRTUAL_SWITCH_REQUIRED = true; private final static int VIRTUAL_SWITCH_LENGTH_MIN = 0; private final static int VIRTUAL_SWITCH_LENGTH_MAX = 200; private final static boolean VIRTUAL_SWITCH_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false; private final static String VIRTUAL_SWITCH_COLUMN = "vswitchName"; @Column(name = VIRTUAL_SWITCH_COLUMN, nullable = !VIRTUAL_SWITCH_REQUIRED, length = VIRTUAL_SWITCH_LENGTH_MAX) private String virtualSwitch; @Required(value = VIRTUAL_SWITCH_REQUIRED) @Length(min = VIRTUAL_SWITCH_LENGTH_MIN, max = VIRTUAL_SWITCH_LENGTH_MAX) @LeadingOrTrailingWhitespace(allowed = VIRTUAL_SWITCH_LEADING_OR_TRAILING_WHITESPACES_ALLOWED) public String getVirtualSwitch() { return this.virtualSwitch; } public void setVirtualSwitch(final String virtualSwitch) { this.virtualSwitch = virtualSwitch; } public final static String IPMI_IP_PROPERTY = "ipmiIP"; private final static boolean IPMI_IP_REQUIRED = false; private final static int IPMI_IP_LENGTH_MIN = 0; private final static int IPMI_IP_LENGTH_MAX = 39; private final static boolean IPMI_IP_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false; private final static String IPMI_IP_COLUMN = "ipmiIP"; @Column(name = IPMI_IP_COLUMN, nullable = !IPMI_IP_REQUIRED, length = IPMI_IP_LENGTH_MAX) private String ipmiIP; @Required(value = IPMI_IP_REQUIRED) @Length(min = IPMI_IP_LENGTH_MIN, max = IPMI_IP_LENGTH_MAX) @LeadingOrTrailingWhitespace(allowed = IPMI_IP_LEADING_OR_TRAILING_WHITESPACES_ALLOWED) public String getIpmiIP() { return this.ipmiIP; } public void setIpmiIP(final String ipmiIP) { this.ipmiIP = ipmiIP; } public final static String IPMI_PORT_PROPERTY = "ipmiPort"; private final static String IPMI_PORT_COLUMN = "ipmiPort"; private final static boolean IPMI_PORT_REQUIRED = false; private final static int IPMI_PORT_MIN = Integer.MIN_VALUE; private final static int IPMI_PORT_MAX = Integer.MAX_VALUE; @Required(value = IPMI_PORT_REQUIRED) @Column(name = IPMI_PORT_COLUMN, nullable = true) @Range(min = IPMI_PORT_MIN, max = IPMI_PORT_MAX) private Integer ipmiPort; public Integer getIpmiPort() { return this.ipmiPort; } public void setIpmiPort(final Integer ipmiPort) { this.ipmiPort = ipmiPort; } public final static String IPMI_USER_PROPERTY = "ipmiUser"; private final static boolean IPMI_USER_REQUIRED = false; private final static int IPMI_USER_LENGTH_MIN = 0; private final static int IPMI_USER_LENGTH_MAX = 255; private final static boolean IPMI_USER_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false; private final static String IPMI_USER_COLUMN = "ipmiUser"; @Column(name = IPMI_USER_COLUMN, nullable = !IPMI_USER_REQUIRED, length = IPMI_USER_LENGTH_MAX) private String ipmiUser; @Required(value = IPMI_USER_REQUIRED) @Length(min = IPMI_USER_LENGTH_MIN, max = IPMI_USER_LENGTH_MAX) @LeadingOrTrailingWhitespace(allowed = IPMI_USER_LEADING_OR_TRAILING_WHITESPACES_ALLOWED) public String getIpmiUser() { return this.ipmiUser; } public void setIpmiUser(final String ipmiUser) { this.ipmiUser = ipmiUser; } public final static String IPMI_PASSWORD_PROPERTY = "ipmiPassword"; private final static boolean IPMI_PASSWORD_REQUIRED = false; private final static int IPMI_PASSWORD_LENGTH_MIN = 0; private final static int IPMI_PASSWORD_LENGTH_MAX = 255; private final static boolean IPMI_PASSWORD_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false; private final static String IPMI_PASSWORD_COLUMN = "ipmiPassword"; @Column(name = IPMI_PASSWORD_COLUMN, nullable = !IPMI_PASSWORD_REQUIRED, length = IPMI_PASSWORD_LENGTH_MAX) private String ipmiPassword; @Required(value = IPMI_PASSWORD_REQUIRED) @Length(min = IPMI_PASSWORD_LENGTH_MIN, max = IPMI_PASSWORD_LENGTH_MAX) @LeadingOrTrailingWhitespace(allowed = IPMI_PASSWORD_LEADING_OR_TRAILING_WHITESPACES_ALLOWED) public String getIpmiPassword() { return this.ipmiPassword; } public void setIpmiPassword(final String ipmiPassword) { this.ipmiPassword = ipmiPassword; } // ********************************* Associations // *************************** public final static String DATACENTER_PROPERTY = "datacenter"; final static boolean DATACENTER_REQUIRED = true; private final static String DATACENTER_ID_COLUMN = "idDataCenter"; @JoinColumn(name = DATACENTER_ID_COLUMN) @ManyToOne(fetch = FetchType.LAZY) @ForeignKey(name = "FK_" + TABLE_NAME + "_datacenter") private Datacenter datacenter; @Required(value = DATACENTER_REQUIRED) public Datacenter getDatacenter() { return this.datacenter; } public void setDatacenter(final Datacenter datacenter) { this.datacenter = datacenter; } public final static String RACK_PROPERTY = "rack"; private final static boolean RACK_REQUIRED = false; private final static String RACK_ID_COLUMN = "idRack"; @JoinColumn(name = RACK_ID_COLUMN) @ManyToOne(fetch = FetchType.LAZY) @ForeignKey(name = "FK_" + TABLE_NAME + "_rack") private Rack rack; @Required(value = RACK_REQUIRED) public Rack getRack() { return this.rack; } public void setRack(final Rack rack) { this.rack = rack; if (rack instanceof UcsRack) { this.setBelongsToManagedRack(Boolean.TRUE); } } public boolean rackIsInDatacenter(final Rack rack) { assert rack != null; return getDatacenter().getId() == rack.getDatacenter().getId(); } public final static String HYPERVISOR_PROPERTY = "hypervisor"; public final static String HYPERVISOR_ID_COLUMN = "hypervisor"; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = Hypervisor.MACHINE_PROPERTY) private Hypervisor hypervisor; @Required(value = false) public Hypervisor getHypervisor() { return this.hypervisor; } @Deprecated // use machine.createHypervisor public void setHypervisor(final Hypervisor hypervisor) { this.hypervisor = hypervisor; } // code in Machine public static final String DATASTORES_ASSOCIATION_TABLE = "datastore_assignment"; public static final String DATASTORES_PROPERTY = "datastores"; static final String DATASTORES_ID_COLUMN = "idDatastore"; static final String MACHINES_ID_COLUMN = "idPhysicalMachine"; @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = DATASTORES_ASSOCIATION_TABLE, joinColumns = {@JoinColumn(name = MACHINES_ID_COLUMN)}, inverseJoinColumns = {@JoinColumn(name = DATASTORES_ID_COLUMN)}) private List<Datastore> datastores = new ArrayList<Datastore>(); public List<Datastore> getDatastores() { if (datastores == null) { datastores = new ArrayList<Datastore>(); } return datastores; } /* package */void addToDatastores(final Datastore value) { assert value != null; assert !this.datastores.contains(value); this.datastores.add(value); } /* package */void removeFromDatastores(final Datastore value) { assert value != null; assert this.datastores.contains(value); this.datastores.remove(value); } public final static String ENTERPRISE_PROPERTY = "enterprise"; private final static String ENTERPRISE_ID_COLUMN = "idEnterprise"; @JoinColumn(name = ENTERPRISE_ID_COLUMN) @ManyToOne(fetch = FetchType.LAZY, optional = true) @ForeignKey(name = "FK_" + TABLE_NAME + "_enterprise") private Enterprise enterprise; @Required(value = false) public Enterprise getEnterprise() { return this.enterprise; } public void setEnterprise(final Enterprise enterprise) { this.enterprise = enterprise; } // public final static String INITIATOR_IQN_PROPERTY = "initiatorIQN"; private final static boolean INITIATOR_IQN_REQUIRED = false; final static int INITIATOR_IQN_LENGTH_MIN = 0; final static int INITIATOR_IQN_LENGTH_MAX = 256; private final static boolean INITIATOR_IQN_LEADING_OR_TRAILING_WHITESPACES_ALLOWED = false; private final static String INITIATOR_IQN_COLUMN = "initiatorIQN"; @Column(name = INITIATOR_IQN_COLUMN, nullable = !INITIATOR_IQN_REQUIRED, length = INITIATOR_IQN_LENGTH_MAX) private String initiatorIQN; // TODO custom IQN validation @Required(value = INITIATOR_IQN_REQUIRED) @Length(min = INITIATOR_IQN_LENGTH_MIN, max = INITIATOR_IQN_LENGTH_MAX) @LeadingOrTrailingWhitespace(allowed = INITIATOR_IQN_LEADING_OR_TRAILING_WHITESPACES_ALLOWED) public String getInitiatorIQN() { return this.initiatorIQN; } public void setInitiatorIQN(final String initiatorIQN) { this.initiatorIQN = initiatorIQN; } // *************************** Mandatory constructors // *********************** public Machine(final Datacenter datacenter, final String name, final String description, final int virtualRamInMb, final int virtualRamUsedInMb, final int virtualCpuCores, final int virtualCpusUsed, final MachineState state, final String virtualSwitch) { setDatacenter(datacenter); setName(name); setDescription(description); setVirtualRamInMb(virtualRamInMb); setVirtualRamUsedInMb(virtualRamUsedInMb); setVirtualCpuCores(virtualCpuCores); setVirtualCpusUsed(virtualCpusUsed); setState(state); setVirtualSwitch(virtualSwitch); } // ********************************** Others // ******************************** public Hypervisor createHypervisor(final HypervisorType type, final String ip, final String ipService, final int port, final String user, final String password) { Hypervisor h = new Hypervisor(this, type, ip, ipService, port, user, password); this.hypervisor = h; return h; } public boolean hasFencingCapabilities() { return getIpmiIP() != null && getIpmiUser() != null && getIpmiPassword() != null; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } // Transient attributes needed to Management Racks functionality @Transient private List<String> listOfMacs; public void setListOfMacs(final List<String> listOfMacs) { this.listOfMacs = listOfMacs; } public List<String> getListOfMacs() { if (listOfMacs == null) { listOfMacs = new ArrayList<String>(); } return listOfMacs; } @Transient private Boolean belongsToManagedRack = Boolean.FALSE; public void setBelongsToManagedRack(final Boolean belongsToManagedRack) { this.belongsToManagedRack = belongsToManagedRack; } public Boolean getBelongsToManagedRack() { if (getRack() != null) { return getRack() instanceof UcsRack; } return this.belongsToManagedRack; } }