/**
* Copyright (C) 2009-2015 Dell, Inc.
* See annotations for authorship information
*
* ====================================================================
* Licensed 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.dasein.cloud.compute;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.dasein.cloud.Tag;
import org.dasein.cloud.Taggable;
import org.dasein.cloud.VisibleScope;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A machine image is an image, template, or similar concept from which virtual machines may be instantiated. The term
* "machine image" is a throwback to when Dasein Cloud supported only machine images. It now supports three
* kinds of images ({@link ImageClass}):
* <ul>
* <li>machine</li>
* <li>kernal</li>
* <li>ramdisk</li>
* </ul>
* <p>
* A cloud may indicate which kinds of images are necessary for the instantiation of a virtual machine via the
* meta-data call {@link VirtualMachineSupport#identifyImageRequirement(ImageClass)}. In practice, just about every
* cloud (if not every cloud) requires a "machine" image and a few clouds optionally allow you to specify
* "ramdisk" and/or "kernel" images.
* </p>
* @author George Reese
* @version 2013.04 added documentation and the idea of data center constraints
* @since unknown
*/
public class MachineImage implements Taggable {
/**
* Constructs a minimally viable image object of the specified image class. Because no image format is specified,
* the type for this image will be {@link MachineImageType#VOLUME}.
* @param ownerId the account number for the account that owns the image
* @param regionId the region ID with which the image is associated
* @param imageId the ID for the newly constructed image
* @param imageClass the image class of the image
* @param state the current state for the image
* @param name the name of the image
* @param description a long description of the function of the image
* @param architecture the architecture on which this image is based
* @param platform the platform built into the image
* @return an image matching the specified parameters
*/
static public @Nonnull MachineImage getInstance(@Nonnull String ownerId, @Nonnull String regionId, @Nonnull String imageId, @Nonnull ImageClass imageClass, @Nonnull MachineImageState state, @Nonnull String name, @Nonnull String description, @Nonnull Architecture architecture, @Nonnull Platform platform) {
@SuppressWarnings("deprecation") MachineImage image = new MachineImage();
image.providerOwnerId = ownerId;
image.providerRegionId = regionId;
image.providerMachineImageId = imageId;
image.name = name;
image.description = description;
image.architecture = architecture;
image.platform = platform;
image.currentState = state;
image.imageClass = imageClass;
image.type = MachineImageType.VOLUME;
image.creationTimestamp = 0L;
image.software = "";
image.minimumDiskSizeGb = 10L;
return image;
}
private long minimumDiskSizeGb;
private Architecture architecture;
private long creationTimestamp;
private MachineImageState currentState;
private String description;
private ImageClass imageClass;
private String kernelImageId;
private String name;
private Platform platform;
private String providerDataCenterId;
private String providerMachineImageId;
private String providerOwnerId;
private String providerRegionId;
private String software;
private MachineImageFormat storageFormat;
private Map<String,String> tags;
private MachineImageType type;
private VisibleScope visibleScope;
private Iterable<MachineImageVolume> volumes;
private boolean sharedWithPublic;
private Map<String,String> providerMetadata;
/**
* Constructs an empty machine image.
* @deprecated Use the static factory methods
*/
public MachineImage() { }
/**
* Indicates the kernel image with which this machine image (only for machine images) is associated.
* @param kernelImageId the image ID of the kernel image with which this machine image is associated
* @return this
*/
public @Nonnull MachineImage associatedWith(@Nonnull String kernelImageId) {
this.kernelImageId = kernelImageId;
return this;
}
/**
* Indicates the data center in which virtual machine instances created from this image must be launched for
* images that are data center constrained.
* @param dataCenterId the ID of the data center to which this image is constrained
* @return this
*/
public @Nonnull MachineImage constrainedTo(@Nonnull String dataCenterId) {
this.providerDataCenterId = dataCenterId;
return this;
}
/**
* Indicates the Unix timestamp when this image was created.
* @param timestamp the Unix timestamp in milliseconds when this image was created
* @return this
*/
public @Nonnull MachineImage createdAt(@Nonnegative long timestamp) {
this.creationTimestamp = timestamp;
return this;
}
/**
* Indicates the machine image type. If not set, the value will default to MachineImageType.VOLUME.
* @param type
* @return this
*/
public @Nonnull MachineImage withType(@Nonnull MachineImageType type) {
this.type = type;
return this;
}
/**
* Indicates what image format in case when type of this image is set MachineImageType.STORAGE.
* This field should generally be ignored for other image types.
* @see org.dasein.cloud.compute.MachineImageType
* @param format
* @return this
*/
public @Nonnull MachineImage withStorageFormat(@Nullable MachineImageFormat format) {
this.storageFormat = format;
return this;
}
@Override
public boolean equals(Object ob) {
if( ob == null ) {
return false;
}
if( ob == this ) {
return true;
}
if( ob instanceof MachineImage ) {
MachineImage image = (MachineImage)ob;
return providerRegionId.equals(image.providerRegionId) && providerMachineImageId.equals(image.providerMachineImageId);
}
return false;
}
/**
* @return the architecture associated with this image
*/
public @Nonnull Architecture getArchitecture() {
return architecture;
}
/**
* Note: this value will return 0L for clouds that don't track creation times.
* @return a Unix timestamp in milliseconds indicating when this image was initially created
*/
public @Nonnegative long getCreationTimestamp() {
return creationTimestamp;
}
/**
* @return the current state of the image as described by the cloud provider
*/
public @Nonnull MachineImageState getCurrentState() {
return currentState;
}
/**
* @return a long description describing this image
*/
public @Nonnull String getDescription() {
return description;
}
/**
* @return the image class of this image
*/
public @Nonnull ImageClass getImageClass() {
return imageClass;
}
/**
* @return the kernel image associated with this machine image (this is a machine image if it is associated with a kernel image)
*/
public @Nullable String getKernelImageId() {
return kernelImageId;
}
/**
* @return the name of the image
*/
public @Nonnull String getName() {
return name;
}
/**
* @return the platform embedded in the image
*/
public @Nonnull Platform getPlatform() {
return platform;
}
/**
* In most clouds, images/templates are not constrained at the data center/availability zone level. In those cases
* (for example, AWS), this value will always be <code>null</code>. If, however, the images/templates you use
* can only be launched into a single data center/availability zone, this will return the ID of that data
* center/availability zone.
* @return the data center into which you can launch VMs (<code>null</code> means you can launch into any data center)
*/
public @Nullable String getProviderDataCenterId() {
return providerDataCenterId;
}
/**
* @return the unique ID for this image as it is identified with the cloud provider
*/
public @Nonnull String getProviderMachineImageId() {
return providerMachineImageId;
}
/**
* @return the account number for the account that owns this image
*/
public @Nonnull String getProviderOwnerId() {
return providerOwnerId;
}
/**
* @return the provider ID of the region to which this image is constrained
*/
public @Nonnull String getProviderRegionId() {
return providerRegionId;
}
/**
* @return a string indicating the software embedded in this image (an empty string indicates no specific software)
*/
public @Nonnull String getSoftware() {
return software;
}
/**
* @return for object store-backed images, the format in which the object(s) are stored
*/
public @Nullable MachineImageFormat getStorageFormat() {
return storageFormat;
}
/**
* Fetches the value of the specified tag key.
* @param tag the key of the tag to be fetched
* @return the value associated with the specified key, if any
*/
public @Nullable Object getTag(@Nonnull String tag) {
return getTags().get(tag);
}
@Override
public @Nonnull Map<String,String> getTags() {
if( tags == null ) {
tags = new HashMap<String,String>();
}
return tags;
}
/**
* There are two types of images in Dasein Cloud: storage images and volume images. A storage image is one that
* is accessible via objects in object storage. You can directly download and optionally upload the image into
* this object storage. Volume images, on the other hand, are sitting on block storage devices in the cloud.
* @return the type of image represented by this image
*/
public @Nonnull MachineImageType getType() {
return type;
}
/**
* @return visible scope of the image
*/
public @Nullable VisibleScope getVisibleScope(){
return this.visibleScope;
}
/**
* Sets visible scope of the image
* @return image instance with visible scope modified
*/
public @Nonnull MachineImage withVisibleScope(@Nullable VisibleScope visibleScope) {
this.visibleScope = visibleScope;
return this;
}
@Override
public int hashCode() {
return (providerOwnerId + providerRegionId + providerMachineImageId).hashCode();
}
@Override
public void setTag(@Nonnull String key, @Nonnull String value) {
getTags().put(key, value);
}
/**
* Clears out any currently set tags and replaces them with the specified list.
* @param properties the list of tag values to be set
*/
public void setTags(Map<String,String> properties) {
getTags().clear();
getTags().putAll(properties);
}
/**
* @return volumes of the image
*/
public @Nullable Iterable<MachineImageVolume> getVolumes() {
return volumes;
}
/**
* Sets volumes of the image
* @return image instance with volumes
*/
public @Nonnull MachineImage withVolumes(@Nullable Iterable<MachineImageVolume> volumes ) {
this.volumes = volumes;
return this;
}
@Override
public String toString() {
return (name + " [" + providerMachineImageId + "]");
}
/**
* Indicates the software embedded in this image.
* @param software the software embedded in this image
* @return this
*/
public @Nonnull MachineImage withSoftware(@Nonnull String software) {
this.software = software;
return this;
}
/**
* Marks image as available to public
* @return this
*/
public MachineImage sharedWithPublic() {
this.sharedWithPublic = true;
return this;
}
/**
* Indicates whether the image is available to public
* @return true if available to public
*/
public boolean isPublic() {
return this.sharedWithPublic;
}
/**
* Cloud-specific metadata that drivers may or may not use for matching products with machine images. This is considered driver-internal.
* @return product metadata
*/
public @Nonnull Map<String, String> getProviderMetadata() {
if( providerMetadata == null ) {
providerMetadata = new HashMap<String, String>();
}
return providerMetadata;
}
public MachineImage withProviderMetadata(@Nonnull Map<String, String> providerMetadata) {
getProviderMetadata().putAll(providerMetadata);
return this;
}
/********************************** DEPRECATED METHODS *******************************************/
/**
* Adds a tag to the current list of tags.
* @param t the tag to be added
* @deprecated Use {@link #setTag(String, String)}
*/
public void addTag(Tag t) {
setTag(t.getKey(), t.getValue());
}
/**
* Adds a tag to the current list of tags.
* @param key the key of the tag
* @param value the value of the tag
* @deprecated Use {@link #setTag(String, String)}
*/
public void addTag(String key, String value) {
setTag(key, value);
}
/**
* Sets the architecture associated with this image.
* @param architecture the architecture associated with this image
* @deprecated Use the static factory methods
*/
public void setArchitecture(@Nonnull Architecture architecture) {
this.architecture = architecture;
}
/**
* Sets the timestamp when this image was created.
* @param creationTimestamp the Unix timestamp in milliseconds when the image was created
* @deprecated Use the static factory methods
*/
public void setCreationTimestamp(@Nonnegative long creationTimestamp) {
this.creationTimestamp = creationTimestamp;
}
/**
* Sets the current state of the image.
* @param currentState the current state of the image
* @deprecated Use the static factory methods
*/
public void setCurrentState(@Nonnull MachineImageState currentState) {
this.currentState = currentState;
}
/**
* Sets the description for the image.
* @param description the image description
* @deprecated Use the static factory methods
*/
public void setDescription(@Nonnull String description) {
this.description = description;
}
/**
* Sets the image class for this image.
* @param imageClass the image class of the image
* @deprecated Use the static factory methods
* @see MachineImage#getImageInstance(String, String, String, ImageClass, MachineImageState, String, String, Architecture, Platform, MachineImageFormat)
*/
public void setImageClass(@Nonnull ImageClass imageClass) {
this.imageClass = imageClass;
}
/**
* Sets the kernel image associated with this machine image.
* @param kernelImageId the kernel image associated with this image
* @deprecated Use the static factory methods
* @see MachineImage#associatedWith(String)
*/
public void setKernelImageId(@Nonnull String kernelImageId) {
this.kernelImageId = kernelImageId;
}
/**
* Sets the name of the image.
* @param name the image name
* @deprecated Use the static factory methods
*/
public void setName(@Nonnull String name) {
this.name = name;
}
/**
* Sets the platform for the image.
* @param platform the platform for the image
* @deprecated Use the static factory methods
*/
public void setPlatform(@Nonnull Platform platform) {
this.platform = platform;
}
/**
* Sets the unique ID of this image.
* @param providerMachineImageId the unique ID of this image
* @deprecated Use the static factory methods
*/
public void setProviderMachineImageId(@Nonnull String providerMachineImageId) {
this.providerMachineImageId = providerMachineImageId;
}
/**
* Sets the account number that owns this image.
* @param providerOwnerId the owner of this image
* @deprecated Use the static factory methods
*/
public void setProviderOwnerId(@Nonnull String providerOwnerId) {
this.providerOwnerId = providerOwnerId;
}
/**
* Sets the region ID of the region associated with this image.
* @param providerRegionId the region ID for this image
* @deprecated Use the static factory methods
*/
public void setProviderRegionId(@Nonnull String providerRegionId) {
this.providerRegionId = providerRegionId;
}
/**
* Sets the software embedded in this image.
* @param software the software embedded in this image
* @deprecated Use the static factory methods
*/
public void setSoftware(@Nonnull String software) {
this.software = software;
}
/**
* Sets the storage format for this storage-backed image.
* @param storageFormat the storage format for the image
* @deprecated Use the static factory methods
*/
public void setStorageFormat(@Nonnull MachineImageFormat storageFormat) {
this.storageFormat = storageFormat;
}
/**
* Sets the type of image.
* @param type the type of image
* @deprecated Use the static factory methods
*/
public void setType(@Nonnull MachineImageType type) {
this.type = type;
}
/**
* Sets visible scope of image
* @param visibleScope
* @deprecated Use the static factory methods
* @see MachineImage#withVisibleScope(org.dasein.cloud.VisibleScope)
*/
public void setVisibleScope(VisibleScope visibleScope){
this.visibleScope = visibleScope;
}
/**
* Constructs a minimally viable image object of the specified image class. Because no image format is specified,
* the type for this image will be {@link MachineImageType#VOLUME}.
* @deprecated
* @see MachineImage#getInstance(String, String, String, ImageClass, MachineImageState, String, String, Architecture, Platform)
* @param ownerId the account number for the account that owns the image
* @param regionId the region ID with which the image is associated
* @param imageId the ID for the newly constructed image
* @param imageClass the image class of the image
* @param state the current state for the image
* @param name the name of the image
* @param description a long description of the function of the image
* @param architecture the architecture on which this image is based
* @param platform the platform built into the image
* @return an image matching the specified parameters
*/
static public @Nonnull MachineImage getImageInstance(@Nonnull String ownerId, @Nonnull String regionId, @Nonnull String imageId, @Nonnull ImageClass imageClass, @Nonnull MachineImageState state, @Nonnull String name, @Nonnull String description, @Nonnull Architecture architecture, @Nonnull Platform platform) {
@SuppressWarnings("deprecation") MachineImage image = new MachineImage();
image.providerOwnerId = ownerId;
image.providerRegionId = regionId;
image.providerMachineImageId = imageId;
image.name = name;
image.description = description;
image.architecture = architecture;
image.platform = platform;
image.currentState = state;
image.imageClass = imageClass;
image.type = MachineImageType.VOLUME;
image.creationTimestamp = 0L;
image.software = "";
return image;
}
/**
* Constructs a minimally viable image object of the specified image class of the {@link MachineImageType#STORAGE} format.
* @deprecated
* @see MachineImage#getInstance(String, String, String, ImageClass, MachineImageState, String, String, Architecture, Platform)
* @param ownerId the account number for the account that owns the image
* @param regionId the region ID with which the image is associated
* @param imageId the ID for the newly constructed image
* @param imageClass the image class of the image
* @param state the current state for the image
* @param name the name of the image
* @param description a long description of the function of the image
* @param architecture the architecture on which this image is based
* @param platform the platform built into the image
* @param format the storage format for {@link MachineImageType#STORAGE} images
* @return an image matching the specified parameters
*/
static public @Nonnull MachineImage getImageInstance(@Nonnull String ownerId, @Nonnull String regionId, @Nonnull String imageId, @Nonnull ImageClass imageClass, @Nonnull MachineImageState state, @Nonnull String name, @Nonnull String description, @Nonnull Architecture architecture, @Nonnull Platform platform, @Nonnull MachineImageFormat format) {
@SuppressWarnings("deprecation") MachineImage image = new MachineImage();
image.providerOwnerId = ownerId;
image.providerRegionId = regionId;
image.providerMachineImageId = imageId;
image.name = name;
image.description = description;
image.architecture = architecture;
image.platform = platform;
image.currentState = state;
image.imageClass = imageClass;
image.type = MachineImageType.STORAGE;
image.storageFormat = format;
image.creationTimestamp = 0L;
image.software = "";
return image;
}
/**
* Constructs a minimally viable machine image object of the specified image class. Because no image format is specified,
* the type for this image will be {@link MachineImageType#VOLUME}.
* @deprecated
* @see MachineImage#getInstance(String, String, String, ImageClass, MachineImageState, String, String, Architecture, Platform)
* @param ownerId the account number for the account that owns the image
* @param regionId the region ID with which the image is associated
* @param imageId the ID for the newly constructed image
* @param state the current state for the image
* @param name the name of the image
* @param description a long description of the function of the image
* @param architecture the architecture on which this image is based
* @param platform the platform built into the image
* @return an image matching the specified parameters
*/
static public @Nonnull MachineImage getMachineImageInstance(@Nonnull String ownerId, @Nonnull String regionId, @Nonnull String imageId, @Nonnull MachineImageState state, @Nonnull String name, @Nonnull String description, @Nonnull Architecture architecture, @Nonnull Platform platform) {
@SuppressWarnings("deprecation") MachineImage image = new MachineImage();
image.providerOwnerId = ownerId;
image.providerRegionId = regionId;
image.providerMachineImageId = imageId;
image.name = name;
image.description = description;
image.architecture = architecture;
image.platform = platform;
image.currentState = state;
image.imageClass = ImageClass.MACHINE;
image.type = MachineImageType.VOLUME;
image.creationTimestamp = 0L;
image.software = "";
return image;
}
/**
* Constructs a minimally viable machine image object of the specified image class of the {@link MachineImageType#STORAGE} format.
* @deprecated
* @see MachineImage#getInstance(String, String, String, ImageClass, MachineImageState, String, String, Architecture, Platform)
* @param ownerId the account number for the account that owns the image
* @param regionId the region ID with which the image is associated
* @param imageId the ID for the newly constructed image
* @param state the current state for the image
* @param name the name of the image
* @param description a long description of the function of the image
* @param architecture the architecture on which this image is based
* @param platform the platform built into the image
* @param format the storage format for {@link MachineImageType#STORAGE} images
* @return an image matching the specified parameters
*/
static public @Nonnull MachineImage getMachineImageInstance(@Nonnull String ownerId, @Nonnull String regionId, @Nonnull String imageId, @Nonnull MachineImageState state, @Nonnull String name, @Nonnull String description, @Nonnull Architecture architecture, @Nonnull Platform platform, @Nonnull MachineImageFormat format) {
@SuppressWarnings("deprecation") MachineImage image = new MachineImage();
image.providerOwnerId = ownerId;
image.providerRegionId = regionId;
image.providerMachineImageId = imageId;
image.name = name;
image.description = description;
image.architecture = architecture;
image.platform = platform;
image.currentState = state;
image.imageClass = ImageClass.MACHINE;
image.type = MachineImageType.STORAGE;
image.storageFormat = format;
image.creationTimestamp = 0L;
image.software = "";
return image;
}
/**
* Constructs a minimally viable image object of the specified image class of the {@link MachineImageType#STORAGE} format.
* @deprecated
* @see MachineImage#getInstance(String, String, String, ImageClass, MachineImageState, String, String, Architecture, Platform)
* @param ownerId the account number for the account that owns the image
* @param regionId the region ID with which the image is associated
* @param imageId the ID for the newly constructed image
* @param imageClass the image class of the image
* @param state the current state for the image
* @param name the name of the image
* @param description a long description of the function of the image
* @param architecture the architecture on which this image is based
* @param platform the platform built into the image
* @param format the storage format for {@link MachineImageType#STORAGE} images
* @param visibleScope the scope defining how visible the image is in the cloud
* @return an image matching the specified parameters
*/
static public @Nonnull MachineImage getImageInstance(@Nonnull String ownerId, @Nonnull String regionId, @Nonnull String imageId, @Nonnull ImageClass imageClass, @Nonnull MachineImageState state, @Nonnull String name, @Nonnull String description, @Nonnull Architecture architecture, @Nonnull Platform platform, @Nonnull MachineImageFormat format, @Nullable VisibleScope visibleScope) {
@SuppressWarnings("deprecation") MachineImage image = new MachineImage();
image.providerOwnerId = ownerId;
image.providerRegionId = regionId;
image.providerMachineImageId = imageId;
image.name = name;
image.description = description;
image.architecture = architecture;
image.platform = platform;
image.currentState = state;
image.imageClass = imageClass;
image.type = MachineImageType.STORAGE;
image.storageFormat = format;
image.creationTimestamp = 0L;
image.software = "";
image.visibleScope = visibleScope;
return image;
}
public long getMinimumDiskSizeGb() {
return minimumDiskSizeGb;
}
public void setMinimumDiskSizeGb(long minimumDiskSizeGb) {
this.minimumDiskSizeGb = minimumDiskSizeGb;
}
}