package org.ovirt.engine.core.common.businessentities.storage;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.validation.constraints.Size;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.ovirt.engine.core.common.businessentities.BusinessEntitiesDefinitions;
import org.ovirt.engine.core.common.businessentities.BusinessEntity;
import org.ovirt.engine.core.common.businessentities.IVdcQueryable;
import org.ovirt.engine.core.common.businessentities.Nameable;
import org.ovirt.engine.core.common.businessentities.ProgressEntity;
import org.ovirt.engine.core.common.validation.annotation.ValidDescription;
import org.ovirt.engine.core.common.validation.annotation.ValidI18NName;
import org.ovirt.engine.core.common.validation.group.CreateEntity;
import org.ovirt.engine.core.common.validation.group.UpdateEntity;
import org.ovirt.engine.core.compat.Guid;
/**
* The disk represents a drive in the VM/Template.<br>
* <br>
* The disk data consists of this entity which holds the immutable fields of the drive, and the DiskImage entity which
* represents the drive's actual data, and contains the mutable fields.<br>
* Each drive can have several of these "images" associated to it, which represent the drive's snapshots - a backup of
* the drive's data at a certain point in time. An image of a snapshot is immutable, and there is usually (in case of a
* VM) one or more mutable images which the VM can run with.<br>
* <br>
* Due to this, the {@link BaseDisk} entity always points to the active mutable image that the VM will run with (or the
* image the Template represents).<br>
* The active image can also be <code>null</code>, in case that it's missing but should be there.
*/
public class BaseDisk implements IVdcQueryable, BusinessEntity<Guid>, ProgressEntity, Nameable {
/**
* Needed for java serialization/deserialization mechanism.
*/
private static final long serialVersionUID = 5883196978129104663L;
/**
* The disk ID uniquely identifies a disk in the system.
*/
private Guid id;
/**
* The alias name of the disk.
*/
@Size(min = 0, max = BusinessEntitiesDefinitions.GENERAL_NAME_SIZE,
groups = { CreateEntity.class, UpdateEntity.class })
@ValidI18NName(message = "VALIDATION_DISK_ALIAS_INVALID", groups = { CreateEntity.class, UpdateEntity.class })
private String diskAlias = "";
/**
* The description of the disk.
*/
@Size(min = 0, max = BusinessEntitiesDefinitions.DISK_DESCRIPTION_MAX_SIZE,
groups = { CreateEntity.class, UpdateEntity.class })
@ValidDescription(message = "VALIDATION_DISK_DESCRIPTION_INVALID", groups = { CreateEntity.class
, UpdateEntity.class })
private String diskDescription;
/**
* A boolean indication whether the disk is shareable.
*/
private boolean shareable;
private Map<Guid, DiskVmElement> diskVmElementsMap = Collections.emptyMap();
private Integer progress;
private DiskContentType contentType;
/**
* @return an unmodifiable collection, we don't want anyone messing with the values without going through the setter
*/
@JsonIgnore
public Collection<DiskVmElement> getDiskVmElements() {
return Collections.unmodifiableCollection(diskVmElementsMap.values());
}
public void setDiskVmElements(Collection<DiskVmElement> diskVmElements) {
// Done Java-7 style since it undergoes GWT compilation, should be revised once this changes
diskVmElementsMap = new HashMap<>();
for (DiskVmElement element : diskVmElements) {
diskVmElementsMap.put(element.getId().getVmId(), element);
}
}
@JsonIgnore
public DiskVmElement getDiskVmElementForVm(Guid vmId) {
return diskVmElementsMap.get(vmId);
}
/**
* Should the disk be wiped after it's deleted.
*/
private Boolean wipeAfterDelete;
/**
* Should disk errors be propagated to the guest?
*/
private PropagateErrors propagateErrors;
private ScsiGenericIO sgio;
private DiskAlignment alignment;
private Date lastAlignmentScan;
private String cinderVolumeType;
public BaseDisk() {
propagateErrors = PropagateErrors.Off;
alignment = DiskAlignment.Unknown;
contentType = DiskContentType.DATA;
}
@Override
public Object getQueryableId() {
return getId();
}
@Override
public Guid getId() {
return id;
}
@Override
public void setId(Guid id) {
this.id = id;
}
public boolean isWipeAfterDelete() {
if (isWipeAfterDeleteSet()) {
return wipeAfterDelete;
}
return false;
}
public boolean isWipeAfterDeleteSet() {
return wipeAfterDelete != null;
}
public void setWipeAfterDelete(boolean wipeAfterDelete) {
this.wipeAfterDelete = wipeAfterDelete;
}
public PropagateErrors getPropagateErrors() {
return propagateErrors;
}
public void setPropagateErrors(PropagateErrors propagateErrors) {
this.propagateErrors = propagateErrors;
}
public String getDiskDescription() {
return diskDescription;
}
public void setDiskDescription(String diskDescription) {
this.diskDescription = diskDescription;
}
public String getDiskAlias() {
return diskAlias;
}
public void setDiskAlias(String diskAlias) {
this.diskAlias = diskAlias == null ? "" : diskAlias;
}
public boolean isShareable() {
return shareable;
}
public void setShareable(boolean shareable) {
this.shareable = shareable;
}
public ScsiGenericIO getSgio() {
return sgio;
}
public void setSgio(ScsiGenericIO sgio) {
this.sgio = sgio;
}
public boolean isScsiPassthrough() {
return getSgio() != null;
}
public DiskAlignment getAlignment() {
return alignment;
}
public void setAlignment(DiskAlignment value) {
alignment = value;
}
public Date getLastAlignmentScan() {
return (lastAlignmentScan != null) ? (Date) lastAlignmentScan.clone() : null;
}
public void setLastAlignmentScan(Date value) {
lastAlignmentScan = (value != null) ? (Date) value.clone() : null;
}
public String getCinderVolumeType() {
return cinderVolumeType;
}
public void setCinderVolumeType(String cinderVolumeType) {
this.cinderVolumeType = cinderVolumeType;
}
@Override
public Integer getProgress() {
return progress;
}
@Override
public void setProgress(Integer progress) {
this.progress = progress;
}
/**
* @return The type of underlying storage implementation.
*/
public DiskStorageType getDiskStorageType() {
// should be implemented in the sub-classes
return null;
}
public DiskContentType getContentType() {
return contentType;
}
public void setContentType(DiskContentType contentType) {
this.contentType = contentType;
}
@Override
public int hashCode() {
return Objects.hash(
id,
diskAlias,
diskDescription,
propagateErrors,
shareable,
wipeAfterDelete,
sgio,
cinderVolumeType,
contentType
);
}
@Override
public String getName() {
return getDiskAlias();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof BaseDisk)) {
return false;
}
BaseDisk other = (BaseDisk) obj;
return Objects.equals(id, other.id)
&& Objects.equals(diskAlias, other.diskAlias)
&& Objects.equals(diskDescription, other.diskDescription)
&& propagateErrors == other.propagateErrors
&& shareable == other.shareable
&& isWipeAfterDelete() == other.isWipeAfterDelete()
&& sgio == other.sgio
&& Objects.equals(cinderVolumeType, other.cinderVolumeType)
&& contentType == other.contentType;
}
}