diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java
new file mode 100644
index 000000000000..0426417a1402
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import com.google.api.services.compute.model.Disk;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Base class for Google Compute Engine disk configuration. A disk can be used as primary storage
+ * for your virtual machine instances. Use {@link StandardDiskConfiguration} to create a standard
+ * disk given disk type and size. Use {@link ImageDiskConfiguration} to create a disk from a Compute
+ * Engine disk image. Use {@link SnapshotDiskConfiguration} to create a disk from a Compute Engine
+ * disk snapshot.
+ *
+ * @see Block Storage
+ */
+public abstract class DiskConfiguration implements Serializable {
+
+ private static final long serialVersionUID = -1783061701255428417L;
+
+ private final Type type;
+ private final Long sizeGb;
+ private final DiskTypeId diskType;
+
+ /**
+ * Type of a Google Compute Engine disk configuration.
+ */
+ public enum Type {
+ /**
+ * A Google Compute Engine standard disk configuration.
+ */
+ STANDARD,
+
+ /**
+ * A Google Compute Engine disk configuration that creates a disk from an image.
+ */
+ IMAGE,
+
+ /**
+ * A Google Compute Engine disk configuration that creates a disk from a snapshot.
+ */
+ SNAPSHOT
+ }
+
+ /**
+ * Base builder for disk configurations.
+ *
+ * @param the disk configuration type
+ * @param the disk configuration builder
+ */
+ public abstract static class Builder> {
+
+ private Type type;
+ private Long sizeGb;
+ private DiskTypeId diskType;
+
+ Builder(Type type) {
+ this.type = type;
+ }
+
+ Builder(Type type, DiskConfiguration diskConfiguration) {
+ this.type = type;
+ this.sizeGb = diskConfiguration.sizeGb;
+ this.diskType = diskConfiguration.diskType;
+ }
+
+ Builder(Type type, Disk diskPb) {
+ this.type = type;
+ this.sizeGb = diskPb.getSizeGb();
+ if (diskPb.getType() != null) {
+ this.diskType = DiskTypeId.fromUrl(diskPb.getType());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected B self() {
+ return (B) this;
+ }
+
+ B type(Type type) {
+ this.type = type;
+ return self();
+ }
+
+ /**
+ * Sets the size of the persistent disk, in GB.
+ */
+ public B sizeGb(Long sizeGb) {
+ this.sizeGb = sizeGb;
+ return self();
+ }
+
+ /**
+ * Sets the identity of the disk diskType.
+ */
+ public B diskType(DiskTypeId diskType) {
+ this.diskType = diskType;
+ return self();
+ }
+
+ /**
+ * Creates an object.
+ */
+ public abstract T build();
+ }
+
+ DiskConfiguration(Builder builder) {
+ this.type = builder.type;
+ this.sizeGb = builder.sizeGb;
+ this.diskType = builder.diskType;
+ }
+
+ /**
+ * Returns the disk configuration's type. This method returns {@link Type#STANDARD} for a standard
+ * configuration that creates a disk given its type and size. This method returns
+ * {@link Type#SNAPSHOT} for a configuration that creates a disk from a Google Compute Engine
+ * snapshot. This method returns {@link Type#IMAGE} for a configuration that creates a disk
+ * from a Google Compute Engine image.
+ */
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Returns the size of the persistent disk, in GB.
+ */
+ public Long sizeGb() {
+ return sizeGb;
+ }
+
+ /**
+ * Returns the identity of the disk type.
+ */
+ public DiskTypeId diskType() {
+ return diskType;
+ }
+
+ /**
+ * Returns a builder for the object.
+ */
+ public abstract Builder toBuilder();
+
+ ToStringHelper toStringHelper() {
+ return MoreObjects.toStringHelper(this)
+ .add("type", type)
+ .add("sizeGb", sizeGb)
+ .add("diskType", diskType);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper().toString();
+ }
+
+ final int baseHashCode() {
+ return Objects.hash(type, sizeGb, diskType);
+ }
+
+ final boolean baseEquals(DiskConfiguration diskConfiguration) {
+ return diskConfiguration != null
+ && getClass().equals(diskConfiguration.getClass())
+ && Objects.equals(toPb(), diskConfiguration.toPb());
+ }
+
+ abstract DiskConfiguration setProjectId(String projectId);
+
+ Disk toPb() {
+ Disk diskPb = new Disk();
+ diskPb.setSizeGb(sizeGb);
+ if (diskType != null) {
+ diskPb.setType(diskType.selfLink());
+ }
+ return diskPb;
+ }
+
+ @SuppressWarnings("unchecked")
+ static T fromPb(Disk diskPb) {
+ if (diskPb.getSourceImage() != null) {
+ return (T) ImageDiskConfiguration.fromPb(diskPb);
+ } else if (diskPb.getSourceSnapshot() != null) {
+ return (T) SnapshotDiskConfiguration.fromPb(diskPb);
+ }
+ return (T) StandardDiskConfiguration.fromPb(diskPb);
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java
new file mode 100644
index 000000000000..6610530e6f09
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.api.services.compute.model.Disk;
+import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A Google Compute Engine persistent disk. A disk can be used as primary storage for your virtual
+ * machine instances.
+ *
+ * @see Block Storage
+ */
+public class DiskInfo implements Serializable {
+
+ static final Function FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public DiskInfo apply(Disk pb) {
+ return DiskInfo.fromPb(pb);
+ }
+ };
+ static final Function TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public Disk apply(DiskInfo diskType) {
+ return diskType.toPb();
+ }
+ };
+
+ private static final long serialVersionUID = -7173418340679279619L;
+ private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private final String id;
+ private final DiskId diskId;
+ private final DiskConfiguration configuration;
+ private final Long creationTimestamp;
+ private final CreationStatus creationStatus;
+ private final String description;
+ private final List licenses;
+ private final List attachedInstances;
+ private final Long lastAttachTimestamp;
+ private final Long lastDetachTimestamp;
+
+ /**
+ * The status of disk creation.
+ */
+ public enum CreationStatus {
+ /**
+ * The disk is being created.
+ */
+ CREATING,
+
+ /**
+ * Disk creation failed.
+ */
+ FAILED,
+
+ /**
+ * The disk has been created and is ready to use.
+ */
+ READY,
+
+ /**
+ * The disk is being restored.
+ */
+ RESTORING
+ }
+
+ /**
+ * Builder for {@code DiskInfo} objects.
+ */
+ public abstract static class Builder {
+
+ abstract Builder id(String id);
+
+ /**
+ * Sets the disk configuration.
+ */
+ public abstract Builder configuration(DiskConfiguration configuration);
+
+ /**
+ * Sets the disk identity.
+ */
+ public abstract Builder diskId(DiskId diskId);
+
+ abstract Builder creationTimestamp(Long creationTimestamp);
+
+ abstract Builder creationStatus(CreationStatus creationStatus);
+
+ /**
+ * Sets an optional textual description of the resource.
+ */
+ public abstract Builder description(String description);
+
+ abstract Builder licenses(List licenses);
+
+ abstract Builder attachedInstances(List attachedInstances);
+
+ abstract Builder lastAttachTimestamp(Long lastAttachTimestamp);
+
+ abstract Builder lastDetachTimestamp(Long lastDetachTimestamp);
+
+ /**
+ * Creates a {@code DiskInfo} object.
+ */
+ public abstract DiskInfo build();
+ }
+
+ static final class BuilderImpl extends Builder {
+
+ private String id;
+ private DiskId diskId;
+ private DiskConfiguration configuration;
+ private Long creationTimestamp;
+ private CreationStatus creationStatus;
+ private String description;
+ private List licenses;
+ private List attachedInstances;
+ private Long lastAttachTimestamp;
+ private Long lastDetachTimestamp;
+
+ BuilderImpl() {}
+
+ BuilderImpl(DiskInfo diskInfo) {
+ this.id = diskInfo.id;
+ this.configuration = diskInfo.configuration;
+ this.creationTimestamp = diskInfo.creationTimestamp;
+ this.creationStatus = diskInfo.creationStatus;
+ this.diskId = diskInfo.diskId;
+ this.description = diskInfo.description;
+ this.licenses = diskInfo.licenses;
+ this.attachedInstances = diskInfo.attachedInstances;
+ this.lastAttachTimestamp = diskInfo.lastAttachTimestamp;
+ this.lastDetachTimestamp = diskInfo.lastDetachTimestamp;
+ }
+
+ BuilderImpl(Disk diskPb) {
+ if (diskPb.getId() != null) {
+ this.id = diskPb.getId().toString();
+ }
+ this.configuration = DiskConfiguration.fromPb(diskPb);
+ if (diskPb.getCreationTimestamp() != null) {
+ this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(diskPb.getCreationTimestamp());
+ }
+ if (diskPb.getStatus() != null) {
+ this.creationStatus = CreationStatus.valueOf(diskPb.getStatus());
+ }
+ this.diskId = DiskId.fromUrl(diskPb.getSelfLink());
+ this.description = diskPb.getDescription();
+ if (diskPb.getLicenses() != null) {
+ this.licenses = Lists.transform(diskPb.getLicenses(), LicenseId.FROM_URL_FUNCTION);
+ }
+ if (diskPb.getUsers() != null) {
+ this.attachedInstances = Lists.transform(diskPb.getUsers(), InstanceId.FROM_URL_FUNCTION);
+ }
+ if (diskPb.getLastAttachTimestamp() != null) {
+ this.lastAttachTimestamp = TIMESTAMP_FORMATTER.parseMillis(diskPb.getLastAttachTimestamp());
+ }
+ if (diskPb.getLastDetachTimestamp() != null) {
+ this.lastDetachTimestamp = TIMESTAMP_FORMATTER.parseMillis(diskPb.getLastDetachTimestamp());
+ }
+ }
+
+ @Override
+ BuilderImpl id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ @Override
+ public BuilderImpl configuration(DiskConfiguration configuration) {
+ this.configuration = checkNotNull(configuration);
+ return this;
+ }
+
+ @Override
+ public BuilderImpl diskId(DiskId diskId) {
+ this.diskId = checkNotNull(diskId);
+ return this;
+ }
+
+ @Override
+ BuilderImpl creationTimestamp(Long creationTimestamp) {
+ this.creationTimestamp = creationTimestamp;
+ return this;
+ }
+
+ @Override
+ BuilderImpl creationStatus(CreationStatus creationStatus) {
+ this.creationStatus = creationStatus;
+ return this;
+ }
+
+ @Override
+ public BuilderImpl description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ @Override
+ BuilderImpl licenses(List licenses) {
+ this.licenses = licenses != null ? ImmutableList.copyOf(licenses) : null;
+ return this;
+ }
+
+ @Override
+ BuilderImpl attachedInstances(List attachedInstances) {
+ this.attachedInstances =
+ attachedInstances != null ? ImmutableList.copyOf(attachedInstances) : null;
+ return this;
+ }
+
+ @Override
+ BuilderImpl lastAttachTimestamp(Long lastAttachTimestamp) {
+ this.lastAttachTimestamp = lastAttachTimestamp;
+ return this;
+ }
+
+ @Override
+ BuilderImpl lastDetachTimestamp(Long lastDetachTimestamp) {
+ this.lastDetachTimestamp = lastDetachTimestamp;
+ return this;
+ }
+
+ @Override
+ public DiskInfo build() {
+ return new DiskInfo(this);
+ }
+ }
+
+ DiskInfo(BuilderImpl builder) {
+ this.id = builder.id;
+ this.configuration = checkNotNull(builder.configuration);
+ this.creationTimestamp = builder.creationTimestamp;
+ this.creationStatus = builder.creationStatus;
+ this.diskId = checkNotNull(builder.diskId);
+ this.description = builder.description;
+ this.licenses = builder.licenses;
+ this.attachedInstances = builder.attachedInstances;
+ this.lastAttachTimestamp = builder.lastAttachTimestamp;
+ this.lastDetachTimestamp = builder.lastDetachTimestamp;
+ }
+
+ /**
+ * Returns the creation timestamp in milliseconds since epoch.
+ */
+ public Long creationTimestamp() {
+ return creationTimestamp;
+ }
+
+ /**
+ * Returns the unique identifier for the disk; defined by the service.
+ */
+ public String id() {
+ return id;
+ }
+
+ /**
+ * Returns the disk configuration.
+ */
+ @SuppressWarnings("unchecked")
+ public T configuration() {
+ return (T) configuration;
+ }
+
+ /**
+ * Returns the disk identity.
+ */
+ public DiskId diskId() {
+ return diskId;
+ }
+
+ /**
+ * Returns the creation status of the disk.
+ */
+ public CreationStatus creationStatus() {
+ return creationStatus;
+ }
+
+ /**
+ * Returns a textual description of the disk.
+ */
+ public String description() {
+ return description;
+ }
+
+ /**
+ * Returns all applicable publicly visible licenses for the disk.
+ */
+ public List licenses() {
+ return licenses;
+ }
+
+ /**
+ * Returns all instances' identities this disk is attached to.
+ */
+ public List attachedInstances() {
+ return attachedInstances;
+ }
+
+ /**
+ * Returns the last attach timestamp in milliseconds since epoch.
+ */
+ public Long lastAttachTimestamp() {
+ return lastAttachTimestamp;
+ }
+
+ /**
+ * Returns the last detach timestamp in milliseconds since epoch.
+ */
+ public Long lastDetachTimestamp() {
+ return lastDetachTimestamp;
+ }
+
+ /**
+ * Returns a builder for the object.
+ */
+ public Builder toBuilder() {
+ return new BuilderImpl(this);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("id", id)
+ .add("diskId", diskId)
+ .add("configuration", configuration)
+ .add("creationTimestamp", creationTimestamp)
+ .add("creationStatus", creationStatus)
+ .add("description", description)
+ .add("licenses", licenses)
+ .add("attachedInstances", attachedInstances)
+ .add("lastAttachTimestamp", lastAttachTimestamp)
+ .add("lastDetachTimestamp", lastDetachTimestamp)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(diskId, configuration, creationTimestamp, creationStatus, description,
+ licenses, attachedInstances, lastAttachTimestamp, lastDetachTimestamp);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj != null
+ && obj.getClass().equals(DiskInfo.class)
+ && Objects.equals(toPb(), ((DiskInfo) obj).toPb());
+ }
+
+ /**
+ * Returns a builder for a {@code DiskInfo} object given its identity and configuration. Use
+ * {@link StandardDiskConfiguration} to create a simple disk given its type and size. Use
+ * {@link SnapshotDiskConfiguration} to create a disk from a snapshot. Use
+ * {@link ImageDiskConfiguration} to create a disk form a disk image.
+ */
+ public static Builder builder(DiskId diskId, DiskConfiguration configuration) {
+ return new BuilderImpl().diskId(diskId).configuration(configuration);
+ }
+
+ /**
+ * Returns a {@code DiskInfo} object given its identity and configuration. Use
+ * {@link StandardDiskConfiguration} to create a simple disk given its type and size. Use
+ * {@link SnapshotDiskConfiguration} to create a disk from a snapshot. Use
+ * {@link ImageDiskConfiguration} to create a disk form a disk image.
+ */
+ public static DiskInfo of(DiskId diskId, DiskConfiguration configuration) {
+ return builder(diskId, configuration).build();
+ }
+
+ DiskInfo setProjectId(String projectId) {
+ return toBuilder()
+ .diskId(diskId.setProjectId(projectId))
+ .configuration(configuration.setProjectId(projectId))
+ .build();
+ }
+
+ Disk toPb() {
+ Disk diskPb = configuration.toPb();
+ if (id != null) {
+ diskPb.setId(new BigInteger(id));
+ }
+ if (creationTimestamp != null) {
+ diskPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp));
+ }
+ diskPb.setZone(diskId.zoneId().selfLink());
+ if (creationStatus != null) {
+ diskPb.setStatus(creationStatus.toString());
+ }
+ diskPb.setName(diskId.disk());
+ diskPb.setDescription(description);
+ diskPb.setSelfLink(diskId.selfLink());
+ if (licenses != null) {
+ diskPb.setLicenses(Lists.transform(licenses, LicenseId.TO_URL_FUNCTION));
+ }
+ if (attachedInstances != null) {
+ diskPb.setUsers(Lists.transform(attachedInstances, InstanceId.TO_URL_FUNCTION));
+ }
+ if (lastAttachTimestamp != null) {
+ diskPb.setLastAttachTimestamp(TIMESTAMP_FORMATTER.print(lastAttachTimestamp));
+ }
+ if (lastDetachTimestamp != null) {
+ diskPb.setLastDetachTimestamp(TIMESTAMP_FORMATTER.print(lastDetachTimestamp));
+ }
+ return diskPb;
+ }
+
+ static DiskInfo fromPb(Disk diskPb) {
+ return new BuilderImpl(diskPb).build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java
new file mode 100644
index 000000000000..fdf616fd78ca
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.api.services.compute.model.Disk;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * A Google Compute Engine disk configuration to create a disk from a Google Compute Engine image.
+ *
+ * @see Block Storage
+ */
+public class ImageDiskConfiguration extends DiskConfiguration {
+
+ private static final long serialVersionUID = 6469117882950722812L;
+
+ private final ImageId sourceImage;
+ private final String sourceImageId;
+
+ /**
+ * A builder for {@code ImageDiskConfiguration} objects.
+ */
+ public static class Builder
+ extends DiskConfiguration.Builder {
+
+ private ImageId sourceImage;
+ private String sourceImageId;
+
+ private Builder() {
+ super(Type.IMAGE);
+ }
+
+ private Builder(ImageDiskConfiguration imageDiskConfiguration) {
+ super(Type.IMAGE, imageDiskConfiguration);
+ this.sourceImage = imageDiskConfiguration.sourceImage;
+ this.sourceImageId = imageDiskConfiguration.sourceImageId;
+ }
+
+ private Builder(Disk diskPb) {
+ super(Type.IMAGE, diskPb);
+ this.sourceImage = ImageId.fromUrl(diskPb.getSourceImage());
+ this.sourceImageId = diskPb.getSourceImageId();
+ }
+
+ /**
+ * Sets the identity of the source image used to create the disk.
+ */
+ public Builder sourceImage(ImageId sourceImage) {
+ this.sourceImage = checkNotNull(sourceImage);
+ return this;
+ }
+
+ Builder sourceImageId(String sourceImageId) {
+ this.sourceImageId = sourceImageId;
+ return this;
+ }
+
+ /**
+ * Creates an {@code ImageDiskConfiguration} object.
+ */
+ @Override
+ public ImageDiskConfiguration build() {
+ return new ImageDiskConfiguration(this);
+ }
+ }
+
+ private ImageDiskConfiguration(Builder builder) {
+ super(builder);
+ this.sourceImage = checkNotNull(builder.sourceImage);
+ this.sourceImageId = builder.sourceImageId;
+ }
+
+ /**
+ * Returns the identity of the source image used to create the disk.
+ */
+ public ImageId sourceImage() {
+ return sourceImage;
+ }
+
+ /**
+ * Returns the ID value of the image used to create this disk. This value identifies the exact
+ * image that was used to create this persistent disk. For example, if you created the persistent
+ * disk from an image that was later deleted and recreated under the same name, the source image
+ * ID would identify the exact version of the image that was used.
+ */
+ public String sourceImageId() {
+ return sourceImageId;
+ }
+
+ @Override
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper()
+ .add("sourceImage", sourceImage)
+ .add("sourceImageId", sourceImageId);
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(baseHashCode(), sourceImage, sourceImageId);
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ return obj instanceof ImageDiskConfiguration && baseEquals((ImageDiskConfiguration) obj);
+ }
+
+ @Override
+ ImageDiskConfiguration setProjectId(String projectId) {
+ Builder builder = toBuilder().sourceImage(sourceImage.setProjectId(projectId));
+ if (diskType() != null) {
+ builder.diskType(diskType().setProjectId(projectId));
+ }
+ return builder.build();
+ }
+
+ @Override
+ Disk toPb() {
+ return super.toPb().setSourceImage(sourceImage.selfLink()).setSourceImageId(sourceImageId);
+ }
+
+ /**
+ * Returns a builder for an {@code ImageDiskConfiguration} object given the image identity.
+ */
+ public static Builder builder(ImageId imageId) {
+ return new Builder().sourceImage(imageId);
+ }
+
+ /**
+ * Returns an {@code ImageDiskConfiguration} object given the image identity.
+ */
+ public static ImageDiskConfiguration of(ImageId imageId) {
+ return builder(imageId).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ static ImageDiskConfiguration fromPb(Disk diskPb) {
+ return new Builder(diskPb).build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java
new file mode 100644
index 000000000000..fbe6249e331f
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.api.services.compute.model.Disk;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * A Google Compute Engine disk configuration to create a disk from a Google Compute Engine
+ * snaoshot.
+ *
+ * @see Block Storage
+ */
+public class SnapshotDiskConfiguration extends DiskConfiguration {
+
+ private static final long serialVersionUID = -1996055058706221049L;
+
+ private final SnapshotId sourceSnapshot;
+ private final String sourceSnapshotId;
+
+ /**
+ * A builder for {@code SnapshotDiskConfiguration} objects.
+ */
+ public static class Builder
+ extends DiskConfiguration.Builder {
+
+ private SnapshotId sourceSnapshot;
+ private String sourceSnapshotId;
+
+ private Builder() {
+ super(Type.SNAPSHOT);
+ }
+
+ private Builder(SnapshotDiskConfiguration snapshotDiskInfo) {
+ super(Type.SNAPSHOT, snapshotDiskInfo);
+ this.sourceSnapshot = snapshotDiskInfo.sourceSnapshot;
+ this.sourceSnapshotId = snapshotDiskInfo.sourceSnapshotId;
+ }
+
+ private Builder(Disk diskPb) {
+ super(Type.SNAPSHOT, diskPb);
+ this.sourceSnapshot = SnapshotId.fromUrl(diskPb.getSourceSnapshot());
+ this.sourceSnapshotId = diskPb.getSourceSnapshotId();
+ }
+
+ /**
+ * Sets the identity of the source snapshot used to create the disk.
+ */
+ public Builder sourceSnapshot(SnapshotId sourceSnapshot) {
+ this.sourceSnapshot = checkNotNull(sourceSnapshot);
+ return this;
+ }
+
+ Builder sourceSnapshotId(String sourceSnapshotId) {
+ this.sourceSnapshotId = sourceSnapshotId;
+ return this;
+ }
+
+ /**
+ * Creates a {@code SnapshotDiskConfiguration} object.
+ */
+ @Override
+ public SnapshotDiskConfiguration build() {
+ return new SnapshotDiskConfiguration(this);
+ }
+ }
+
+ private SnapshotDiskConfiguration(Builder builder) {
+ super(builder);
+ this.sourceSnapshot = checkNotNull(builder.sourceSnapshot);
+ this.sourceSnapshotId = builder.sourceSnapshotId;
+ }
+
+ /**
+ * Returns the identity of the source snapshot used to create the disk.
+ */
+ public SnapshotId sourceSnapshot() {
+ return sourceSnapshot;
+ }
+
+ /**
+ * Returns the unique ID of the snapshot used to create this disk. This value identifies the exact
+ * snapshot that was used to create the persistent disk. For example, if you created the
+ * persistent disk from a snapshot that was later deleted and recreated under the same name, the
+ * source snapshot ID would identify the exact version of the snapshot that was used.
+ */
+ public String sourceSnapshotId() {
+ return sourceSnapshotId;
+ }
+
+ @Override
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper()
+ .add("sourceSnapshot", sourceSnapshot)
+ .add("sourceSnapshotId", sourceSnapshotId);
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(baseHashCode(), sourceSnapshot, sourceSnapshotId);
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ return obj instanceof SnapshotDiskConfiguration && baseEquals((SnapshotDiskConfiguration) obj);
+ }
+
+ @Override
+ SnapshotDiskConfiguration setProjectId(String projectId) {
+ Builder builder = toBuilder().sourceSnapshot(sourceSnapshot.setProjectId(projectId));
+ if (diskType() != null) {
+ builder.diskType(diskType().setProjectId(projectId));
+ }
+ return builder.build();
+ }
+
+ @Override
+ Disk toPb() {
+ return super.toPb()
+ .setSourceSnapshot(sourceSnapshot.selfLink())
+ .setSourceSnapshotId(sourceSnapshotId);
+ }
+
+ /**
+ * Returns a builder for a {@code SnapshotDiskConfiguration} object given the snapshot identity.
+ */
+ static Builder builder(SnapshotId sourceSnapshot) {
+ return new Builder().sourceSnapshot(sourceSnapshot);
+ }
+
+ /**
+ * Returns a {@code SnapshotDiskConfiguration} object given the snapshot identity.
+ */
+ public static SnapshotDiskConfiguration of(SnapshotId sourceSnapshot) {
+ return builder(sourceSnapshot).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ static SnapshotDiskConfiguration fromPb(Disk diskPb) {
+ return new Builder(diskPb).build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java
new file mode 100644
index 000000000000..2c6563859bb3
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import com.google.api.services.compute.model.Disk;
+
+import java.util.Objects;
+
+/**
+ * A Google Compute Engine standard persistent disk configuration. Allows to create a disk given its
+ * type and size.
+ *
+ * @see Block Storage
+ */
+public class StandardDiskConfiguration extends DiskConfiguration {
+
+ private static final long serialVersionUID = -6974045909359567054L;
+
+ /**
+ * A builder for {@code StandardDiskConfiguration} objects.
+ */
+ public static class Builder
+ extends DiskConfiguration.Builder {
+
+ private Builder() {
+ super(Type.STANDARD);
+ }
+
+ private Builder(StandardDiskConfiguration diskInfo) {
+ super(Type.STANDARD, diskInfo);
+ }
+
+ private Builder(Disk diskPb) {
+ super(Type.STANDARD, diskPb);
+ }
+
+ /**
+ * Creates a {@code StandardDiskConfiguration} object.
+ */
+ @Override
+ public StandardDiskConfiguration build() {
+ return new StandardDiskConfiguration(this);
+ }
+ }
+
+ private StandardDiskConfiguration(StandardDiskConfiguration.Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(baseHashCode());
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ return obj instanceof StandardDiskConfiguration && baseEquals((StandardDiskConfiguration) obj);
+ }
+
+ @Override
+ StandardDiskConfiguration setProjectId(String projectId) {
+ if (diskType() == null || diskType().project() != null) {
+ return this;
+ }
+ return toBuilder().diskType(diskType().setProjectId(projectId)).build();
+ }
+
+ /**
+ * Returns a builder for a {@code StandardDiskConfiguration} object.
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a {@code StandardDiskConfiguration} object given the disk type.
+ */
+ public static StandardDiskConfiguration of(DiskTypeId diskType) {
+ return builder().diskType(diskType).build();
+ }
+
+ /**
+ * Returns a {@code StandardDiskConfiguration} object given the disk size in GB.
+ */
+ public static StandardDiskConfiguration of(long sizeGb) {
+ return builder().sizeGb(sizeGb).build();
+ }
+
+ /**
+ * Returns a {@code StandardDiskConfiguration} object given the disk type and size in GB.
+ */
+ public static StandardDiskConfiguration of(DiskTypeId diskType, long sizeGb) {
+ return builder().diskType(diskType).sizeGb(sizeGb).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ static StandardDiskConfiguration fromPb(Disk diskPb) {
+ return new Builder(diskPb).build();
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java
new file mode 100644
index 000000000000..ba67f9b8c825
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import com.google.api.services.compute.model.Disk;
+import com.google.common.collect.ImmutableList;
+import com.google.gcloud.compute.DiskInfo.CreationStatus;
+
+import org.junit.Test;
+
+import java.util.List;
+
+public class DiskInfoTest {
+
+ private static final String ID = "42";
+ private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk");
+ private static final Long CREATION_TIMESTAMP = 1453293540000L;
+ private static final CreationStatus CREATION_STATUS = CreationStatus.READY;
+ private static final String DESCRIPTION = "description";
+ private static final Long SIZE_GB = 500L;
+ private static final DiskTypeId TYPE = DiskTypeId.of("project", "zone", "disk");
+ private static final List LICENSES = ImmutableList.of(
+ LicenseId.of("project", "license1"), LicenseId.of("project", "license2"));
+ private static final List ATTACHED_INSTANCES = ImmutableList.of(
+ InstanceId.of("project", "zone", "instance1"),
+ InstanceId.of("project", "zone", "instance2"));
+ private static final SnapshotId SNAPSHOT = SnapshotId.of("project", "snapshot");
+ private static final ImageId IMAGE = ImageId.of("project", "image");
+ private static final String SNAPSHOT_ID = "snapshotId";
+ private static final String IMAGE_ID = "snapshotId";
+ private static final Long LAST_ATTACH_TIMESTAMP = 1453293600000L;
+ private static final Long LAST_DETACH_TIMESTAMP = 1453293660000L;
+ private static final StandardDiskConfiguration DISK_CONFIGURATION =
+ StandardDiskConfiguration.builder()
+ .sizeGb(SIZE_GB)
+ .diskType(TYPE)
+ .build();
+ private static final SnapshotDiskConfiguration SNAPSHOT_DISK_CONFIGURATION =
+ SnapshotDiskConfiguration.builder(SNAPSHOT)
+ .sizeGb(SIZE_GB)
+ .diskType(TYPE)
+ .sourceSnapshotId(SNAPSHOT_ID)
+ .build();
+ private static final ImageDiskConfiguration IMAGE_DISK_CONFIGURATION =
+ ImageDiskConfiguration.builder(IMAGE)
+ .sizeGb(SIZE_GB)
+ .diskType(TYPE)
+ .sourceImageId(IMAGE_ID)
+ .build();
+ private static final DiskInfo DISK_INFO = DiskInfo.builder(DISK_ID, DISK_CONFIGURATION)
+ .id(ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .creationStatus(CREATION_STATUS)
+ .description(DESCRIPTION)
+ .licenses(LICENSES)
+ .attachedInstances(ATTACHED_INSTANCES)
+ .build();
+ private static final DiskInfo SNAPSHOT_DISK_INFO =
+ DiskInfo.builder(DISK_ID, SNAPSHOT_DISK_CONFIGURATION)
+ .id(ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .creationStatus(CREATION_STATUS)
+ .description(DESCRIPTION)
+ .licenses(LICENSES)
+ .attachedInstances(ATTACHED_INSTANCES)
+ .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP)
+ .lastDetachTimestamp(LAST_DETACH_TIMESTAMP)
+ .build();
+ private static final DiskInfo IMAGE_DISK_INFO =
+ DiskInfo.builder(DISK_ID, IMAGE_DISK_CONFIGURATION)
+ .id(ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .creationStatus(CREATION_STATUS)
+ .description(DESCRIPTION)
+ .licenses(LICENSES)
+ .attachedInstances(ATTACHED_INSTANCES)
+ .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP)
+ .lastDetachTimestamp(LAST_DETACH_TIMESTAMP)
+ .build();
+
+ @Test
+ public void testToBuilder() {
+ compareDiskInfo(DISK_INFO, DISK_INFO.toBuilder().build());
+ compareDiskInfo(IMAGE_DISK_INFO, IMAGE_DISK_INFO.toBuilder().build());
+ compareDiskInfo(SNAPSHOT_DISK_INFO, SNAPSHOT_DISK_INFO.toBuilder().build());
+ DiskInfo diskInfo = DISK_INFO.toBuilder().description("newDescription").build();
+ assertEquals("newDescription", diskInfo.description());
+ diskInfo = diskInfo.toBuilder().description("description").build();
+ compareDiskInfo(DISK_INFO, diskInfo);
+ }
+
+ @Test
+ public void testToBuilderIncomplete() {
+ DiskInfo diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION);
+ assertEquals(diskInfo, diskInfo.toBuilder().build());
+ diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION);
+ assertEquals(diskInfo, diskInfo.toBuilder().build());
+ diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION);
+ assertEquals(diskInfo, diskInfo.toBuilder().build());
+ }
+
+ @Test
+ public void testBuilder() {
+ assertEquals(ID, DISK_INFO.id());
+ assertEquals(DISK_CONFIGURATION, DISK_INFO.configuration());
+ assertEquals(CREATION_TIMESTAMP, DISK_INFO.creationTimestamp());
+ assertEquals(CREATION_STATUS, DISK_INFO.creationStatus());
+ assertEquals(DESCRIPTION, DISK_INFO.description());
+ assertEquals(LICENSES, DISK_INFO.licenses());
+ assertEquals(ATTACHED_INSTANCES, DISK_INFO.attachedInstances());
+ assertEquals(ID, IMAGE_DISK_INFO.id());
+ assertEquals(IMAGE_DISK_CONFIGURATION, IMAGE_DISK_INFO.configuration());
+ assertEquals(CREATION_TIMESTAMP, IMAGE_DISK_INFO.creationTimestamp());
+ assertEquals(CREATION_STATUS, IMAGE_DISK_INFO.creationStatus());
+ assertEquals(DESCRIPTION, IMAGE_DISK_INFO.description());
+ assertEquals(LICENSES, IMAGE_DISK_INFO.licenses());
+ assertEquals(ATTACHED_INSTANCES, IMAGE_DISK_INFO.attachedInstances());
+ assertEquals(ID, SNAPSHOT_DISK_INFO.id());
+ assertEquals(SNAPSHOT_DISK_CONFIGURATION, SNAPSHOT_DISK_INFO.configuration());
+ assertEquals(CREATION_TIMESTAMP, SNAPSHOT_DISK_INFO.creationTimestamp());
+ assertEquals(CREATION_STATUS, SNAPSHOT_DISK_INFO.creationStatus());
+ assertEquals(DESCRIPTION, SNAPSHOT_DISK_INFO.description());
+ assertEquals(LICENSES, SNAPSHOT_DISK_INFO.licenses());
+ assertEquals(ATTACHED_INSTANCES, SNAPSHOT_DISK_INFO.attachedInstances());
+ }
+
+ @Test
+ public void testOf() {
+ DiskInfo diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION);
+ assertNull(diskInfo.id());
+ assertEquals(DISK_ID, diskInfo.diskId());
+ assertEquals(DISK_CONFIGURATION, diskInfo.configuration());
+ assertNull(diskInfo.creationTimestamp());
+ assertNull(diskInfo.creationStatus());
+ assertNull(diskInfo.description());
+ assertNull(diskInfo.licenses());
+ assertNull(diskInfo.attachedInstances());
+ diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION);
+ assertNull(diskInfo.id());
+ assertEquals(DISK_ID, diskInfo.diskId());
+ assertEquals(IMAGE_DISK_CONFIGURATION, diskInfo.configuration());
+ assertNull(diskInfo.creationTimestamp());
+ assertNull(diskInfo.creationStatus());
+ assertNull(diskInfo.description());
+ assertNull(diskInfo.licenses());
+ assertNull(diskInfo.attachedInstances());
+ diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION);
+ assertNull(diskInfo.id());
+ assertEquals(DISK_ID, diskInfo.diskId());
+ assertEquals(SNAPSHOT_DISK_CONFIGURATION, diskInfo.configuration());
+ assertNull(diskInfo.creationTimestamp());
+ assertNull(diskInfo.creationStatus());
+ assertNull(diskInfo.description());
+ assertNull(diskInfo.licenses());
+ assertNull(diskInfo.attachedInstances());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ DiskInfo diskInfo = DiskInfo.fromPb(DISK_INFO.toPb());
+ compareDiskInfo(DISK_INFO, diskInfo);
+ diskInfo = DiskInfo.fromPb(SNAPSHOT_DISK_INFO.toPb());
+ compareDiskInfo(SNAPSHOT_DISK_INFO, diskInfo);
+ diskInfo = DiskInfo.fromPb(IMAGE_DISK_INFO.toPb());
+ compareDiskInfo(IMAGE_DISK_INFO, diskInfo);
+ Disk disk = new Disk()
+ .setSelfLink(DISK_ID.selfLink())
+ .setType(TYPE.selfLink())
+ .setSizeGb(SIZE_GB);
+ diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION);
+ compareDiskInfo(diskInfo, DiskInfo.fromPb(disk));
+ disk = new Disk()
+ .setType(TYPE.selfLink())
+ .setSizeGb(SIZE_GB)
+ .setSelfLink(DISK_ID.selfLink())
+ .setSourceSnapshotId(SNAPSHOT_ID)
+ .setSourceSnapshot(SNAPSHOT.selfLink());
+ diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION);
+ compareDiskInfo(diskInfo, DiskInfo.fromPb(disk));
+ disk = new Disk()
+ .setType(TYPE.selfLink())
+ .setSizeGb(SIZE_GB)
+ .setSelfLink(DISK_ID.selfLink())
+ .setSourceImageId(IMAGE_ID)
+ .setSourceImage(IMAGE.selfLink());
+ diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION);
+ compareDiskInfo(diskInfo, DiskInfo.fromPb(disk));
+ }
+
+ @Test
+ public void testSetProjectId() {
+ StandardDiskConfiguration standardDiskConfiguration = DISK_CONFIGURATION.toBuilder()
+ .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType()))
+ .build();
+ DiskInfo diskInfo = DISK_INFO.toBuilder()
+ .diskId(DiskId.of(DISK_ID.zone(), DISK_ID.disk()))
+ .configuration(standardDiskConfiguration)
+ .build();
+ compareDiskInfo(DISK_INFO, diskInfo.setProjectId("project"));
+ SnapshotDiskConfiguration snapshotDiskConfiguration = SNAPSHOT_DISK_CONFIGURATION.toBuilder()
+ .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType()))
+ .sourceSnapshot(SnapshotId.of(SNAPSHOT.snapshot()))
+ .build();
+ diskInfo = SNAPSHOT_DISK_INFO.toBuilder()
+ .diskId(DiskId.of(DISK_ID.zone(), DISK_ID.disk()))
+ .configuration(snapshotDiskConfiguration)
+ .build();
+ compareDiskInfo(SNAPSHOT_DISK_INFO, diskInfo.setProjectId("project"));
+ ImageDiskConfiguration imageDiskConfiguration = IMAGE_DISK_CONFIGURATION.toBuilder()
+ .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType()))
+ .sourceImage(ImageId.of(IMAGE.image()))
+ .build();
+ diskInfo = IMAGE_DISK_INFO.toBuilder()
+ .diskId(DiskId.of(DISK_ID.zone(), DISK_ID.disk()))
+ .configuration(imageDiskConfiguration)
+ .build();
+ compareDiskInfo(IMAGE_DISK_INFO, diskInfo.setProjectId("project"));
+ }
+
+ public void compareDiskInfo(DiskInfo expected, DiskInfo value) {
+ assertEquals(expected, value);
+ assertEquals(expected.configuration(), value.configuration());
+ assertEquals(expected.id(), value.id());
+ assertEquals(expected.creationTimestamp(), value.creationTimestamp());
+ assertEquals(expected.creationStatus(), value.creationStatus());
+ assertEquals(expected.description(), value.description());
+ assertEquals(expected.licenses(), value.licenses());
+ assertEquals(expected.attachedInstances(), value.attachedInstances());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java
new file mode 100644
index 000000000000..4411ee8c358e
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import com.google.gcloud.compute.DiskConfiguration.Type;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ImageDiskConfigurationTest {
+
+ private static final Long SIZE = 42L;
+ private static final DiskTypeId DISK_TYPE = DiskTypeId.of("project", "zone", "type");
+ private static final ImageId IMAGE = ImageId.of("project", "image");
+ private static final String IMAGE_ID = "imageId";
+ private static final ImageDiskConfiguration DISK_CONFIGURATION =
+ ImageDiskConfiguration.builder(IMAGE)
+ .sizeGb(SIZE)
+ .diskType(DISK_TYPE)
+ .sourceImageId(IMAGE_ID)
+ .build();
+
+ @Test
+ public void testToBuilder() {
+ compareImageDiskConfiguration(DISK_CONFIGURATION, DISK_CONFIGURATION.toBuilder().build());
+ ImageId newImageId = ImageId.of("newProjet", "newImage");
+ ImageDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder()
+ .sizeGb(24L)
+ .sourceImage(newImageId)
+ .sourceImageId("newImageId")
+ .build();
+ assertEquals(24L, diskConfiguration.sizeGb().longValue());
+ assertEquals(newImageId, diskConfiguration.sourceImage());
+ assertEquals("newImageId", diskConfiguration.sourceImageId());
+ diskConfiguration = diskConfiguration.toBuilder()
+ .sizeGb(SIZE)
+ .sourceImage(IMAGE)
+ .sourceImageId(IMAGE_ID)
+ .build();
+ compareImageDiskConfiguration(DISK_CONFIGURATION, diskConfiguration);
+ }
+
+ @Test
+ public void testToBuilderIncomplete() {
+ ImageDiskConfiguration diskConfiguration = ImageDiskConfiguration.of(IMAGE);
+ compareImageDiskConfiguration(diskConfiguration, diskConfiguration.toBuilder().build());
+ }
+
+ @Test
+ public void testBuilder() {
+ assertEquals(DISK_TYPE, DISK_CONFIGURATION.diskType());
+ assertEquals(SIZE, DISK_CONFIGURATION.sizeGb());
+ assertEquals(IMAGE, DISK_CONFIGURATION.sourceImage());
+ assertEquals(IMAGE_ID, DISK_CONFIGURATION.sourceImageId());
+ assertEquals(Type.IMAGE, DISK_CONFIGURATION.type());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ assertTrue(DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb())
+ instanceof ImageDiskConfiguration);
+ compareImageDiskConfiguration(DISK_CONFIGURATION,
+ DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb()));
+ }
+
+ @Test
+ public void testOf() {
+ ImageDiskConfiguration configuration = ImageDiskConfiguration.of(IMAGE);
+ assertNull(configuration.diskType());
+ assertNull(configuration.sizeGb());
+ assertNull(configuration.sourceImageId());
+ assertEquals(IMAGE, configuration.sourceImage());
+ assertEquals(Type.IMAGE, configuration.type());
+ }
+
+ @Test
+ public void testSetProjectId() {
+ ImageDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder()
+ .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType()))
+ .sourceImage(ImageId.of(IMAGE.image()))
+ .build();
+ compareImageDiskConfiguration(DISK_CONFIGURATION, diskConfiguration.setProjectId("project"));
+ }
+
+ private void compareImageDiskConfiguration(ImageDiskConfiguration expected,
+ ImageDiskConfiguration value) {
+ assertEquals(expected, value);
+ assertEquals(expected.diskType(), value.diskType());
+ assertEquals(expected.sizeGb(), value.sizeGb());
+ assertEquals(expected.sourceImage(), value.sourceImage());
+ assertEquals(expected.sourceImageId(), value.sourceImageId());
+ assertEquals(expected.type(), value.type());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java
index 0251dca1fc39..57736854091f 100644
--- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java
@@ -156,6 +156,13 @@ public class SerializationTest {
private static final ImageInfo IMAGE_INFO = ImageInfo.of(IMAGE_ID, DISK_IMAGE_CONFIGURATION);
private static final Image IMAGE =
new Image.Builder(COMPUTE, IMAGE_ID, DISK_IMAGE_CONFIGURATION).build();
+ private static final StandardDiskConfiguration STANDARD_DISK_CONFIGURATION =
+ StandardDiskConfiguration.of(DISK_TYPE_ID);
+ private static final ImageDiskConfiguration IMAGE_DISK_CONFIGURATION =
+ ImageDiskConfiguration.of(IMAGE_ID);
+ private static final SnapshotDiskConfiguration SNAPSHOT_DISK_CONFIGURATION =
+ SnapshotDiskConfiguration.of(SNAPSHOT_ID);
+ private static final DiskInfo DISK_INFO = DiskInfo.of(DISK_ID, STANDARD_DISK_CONFIGURATION);
private static final Compute.DiskTypeOption DISK_TYPE_OPTION =
Compute.DiskTypeOption.fields();
private static final Compute.DiskTypeFilter DISK_TYPE_FILTER =
@@ -232,12 +239,13 @@ public void testModelAndRequests() throws Exception {
INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID,
REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE,
ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID,
- DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, IMAGE, DISK_TYPE_OPTION,
- DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION,
- MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION,
- MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION,
- ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION,
- OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER,
+ DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO,
+ STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION,
+ DISK_INFO, IMAGE, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION,
+ DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER,
+ MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER,
+ REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION,
+ OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER,
ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER,
SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION};
for (Serializable obj : objects) {
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java
new file mode 100644
index 000000000000..ecbe49dc9628
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import com.google.gcloud.compute.DiskConfiguration.Type;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class SnapshotDiskConfigurationTest {
+
+ private static final Long SIZE = 42L;
+ private static final DiskTypeId DISK_TYPE = DiskTypeId.of("project", "zone", "type");
+ private static final SnapshotId SNAPSHOT = SnapshotId.of("project", "snapshot");
+ private static final String SNAPSHOT_ID = "snapshotId";
+ private static final SnapshotDiskConfiguration DISK_CONFIGURATION =
+ SnapshotDiskConfiguration.builder(SNAPSHOT)
+ .sizeGb(SIZE)
+ .diskType(DISK_TYPE)
+ .sourceSnapshotId(SNAPSHOT_ID)
+ .build();
+
+ @Test
+ public void testToBuilder() {
+ compareSnapshotDiskConfiguration(DISK_CONFIGURATION, DISK_CONFIGURATION.toBuilder().build());
+ SnapshotId newSnapshot = SnapshotId.of("newProjet", "newSnapshot");
+ SnapshotDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder()
+ .sizeGb(24L)
+ .sourceSnapshot(newSnapshot)
+ .sourceSnapshotId("newSnapshotId")
+ .build();
+ assertEquals(24L, diskConfiguration.sizeGb().longValue());
+ assertEquals(newSnapshot, diskConfiguration.sourceSnapshot());
+ assertEquals("newSnapshotId", diskConfiguration.sourceSnapshotId());
+ diskConfiguration = diskConfiguration.toBuilder()
+ .sizeGb(SIZE)
+ .sourceSnapshot(SNAPSHOT)
+ .sourceSnapshotId(SNAPSHOT_ID)
+ .build();
+ compareSnapshotDiskConfiguration(DISK_CONFIGURATION, diskConfiguration);
+ }
+
+ @Test
+ public void testToBuilderIncomplete() {
+ SnapshotDiskConfiguration diskConfiguration = SnapshotDiskConfiguration.of(SNAPSHOT);
+ compareSnapshotDiskConfiguration(diskConfiguration, diskConfiguration.toBuilder().build());
+ }
+
+ @Test
+ public void testBuilder() {
+ assertEquals(DISK_TYPE, DISK_CONFIGURATION.diskType());
+ assertEquals(SIZE, DISK_CONFIGURATION.sizeGb());
+ assertEquals(SNAPSHOT, DISK_CONFIGURATION.sourceSnapshot());
+ assertEquals(SNAPSHOT_ID, DISK_CONFIGURATION.sourceSnapshotId());
+ assertEquals(Type.SNAPSHOT, DISK_CONFIGURATION.type());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ assertTrue(DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb())
+ instanceof SnapshotDiskConfiguration);
+ compareSnapshotDiskConfiguration(DISK_CONFIGURATION,
+ DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb()));
+ }
+
+ @Test
+ public void testOf() {
+ SnapshotDiskConfiguration configuration = SnapshotDiskConfiguration.of(SNAPSHOT);
+ assertNull(configuration.diskType());
+ assertNull(configuration.sizeGb());
+ assertNull(configuration.sourceSnapshotId());
+ assertEquals(SNAPSHOT, configuration.sourceSnapshot());
+ assertEquals(Type.SNAPSHOT, configuration.type());
+ }
+
+ @Test
+ public void testSetProjectId() {
+ SnapshotDiskConfiguration configuration = DISK_CONFIGURATION.toBuilder()
+ .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType()))
+ .sourceSnapshot(SnapshotId.of(SNAPSHOT.snapshot()))
+ .build();
+ compareSnapshotDiskConfiguration(DISK_CONFIGURATION, configuration.setProjectId("project"));
+ }
+
+ private void compareSnapshotDiskConfiguration(SnapshotDiskConfiguration expected,
+ SnapshotDiskConfiguration value) {
+ assertEquals(expected, value);
+ assertEquals(expected.diskType(), value.diskType());
+ assertEquals(expected.sizeGb(), value.sizeGb());
+ assertEquals(expected.sourceSnapshot(), value.sourceSnapshot());
+ assertEquals(expected.sourceSnapshotId(), value.sourceSnapshotId());
+ assertEquals(expected.type(), value.type());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java
new file mode 100644
index 000000000000..f5ea642b407a
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * 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 com.google.gcloud.compute;
+
+import com.google.gcloud.compute.DiskConfiguration.Type;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class StandardDiskConfigurationTest {
+
+ private static final Long SIZE = 42L;
+ private static final DiskTypeId DISK_TYPE = DiskTypeId.of("project", "zone", "type");
+ private static final StandardDiskConfiguration DISK_CONFIGURATION =
+ StandardDiskConfiguration.builder()
+ .sizeGb(SIZE)
+ .diskType(DISK_TYPE)
+ .build();
+
+ @Test
+ public void testToBuilder() {
+ compareDefaultDiskConfiguration(DISK_CONFIGURATION, DISK_CONFIGURATION.toBuilder().build());
+ StandardDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder()
+ .sizeGb(24L)
+ .build();
+ assertEquals(24L, diskConfiguration.sizeGb().longValue());
+ diskConfiguration = diskConfiguration.toBuilder()
+ .sizeGb(SIZE)
+ .build();
+ compareDefaultDiskConfiguration(DISK_CONFIGURATION, diskConfiguration);
+ }
+
+ @Test
+ public void testToBuilderIncomplete() {
+ StandardDiskConfiguration diskConfiguration = StandardDiskConfiguration.of(DISK_TYPE);
+ compareDefaultDiskConfiguration(diskConfiguration, diskConfiguration.toBuilder().build());
+ }
+
+ @Test
+ public void testBuilder() {
+ assertEquals(DISK_TYPE, DISK_CONFIGURATION.diskType());
+ assertEquals(SIZE, DISK_CONFIGURATION.sizeGb());
+ assertEquals(Type.STANDARD, DISK_CONFIGURATION.type());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ assertTrue(DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb())
+ instanceof StandardDiskConfiguration);
+ compareDefaultDiskConfiguration(DISK_CONFIGURATION,
+ DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb()));
+ }
+
+ @Test
+ public void testOf() {
+ StandardDiskConfiguration configuration = StandardDiskConfiguration.of(DISK_TYPE);
+ assertEquals(DISK_TYPE, configuration.diskType());
+ assertNull(configuration.sizeGb());
+ assertEquals(Type.STANDARD, configuration.type());
+ configuration = StandardDiskConfiguration.of(DISK_TYPE, SIZE);
+ assertEquals(DISK_TYPE, configuration.diskType());
+ assertEquals(SIZE, configuration.sizeGb());
+ assertEquals(Type.STANDARD, configuration.type());
+ configuration = StandardDiskConfiguration.of(SIZE);
+ assertNull(configuration.diskType());
+ assertEquals(SIZE, configuration.sizeGb());
+ assertEquals(Type.STANDARD, configuration.type());
+ }
+
+ @Test
+ public void testSetProjectId() {
+ StandardDiskConfiguration configuration = DISK_CONFIGURATION.toBuilder()
+ .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType()))
+ .build();
+ compareDefaultDiskConfiguration(DISK_CONFIGURATION, configuration.setProjectId("project"));
+ }
+
+ private void compareDefaultDiskConfiguration(StandardDiskConfiguration expected,
+ StandardDiskConfiguration value) {
+ assertEquals(expected, value);
+ assertEquals(expected.diskType(), value.diskType());
+ assertEquals(expected.sizeGb(), value.sizeGb());
+ assertEquals(expected.type(), value.type());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}