diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md
new file mode 100644
index 000000000000..d1909f904095
--- /dev/null
+++ b/gcloud-java-compute/README.md
@@ -0,0 +1,101 @@
+Google Cloud Java Client for Compute (Alpha)
+====================================
+
+Java idiomatic client for [Google Cloud Compute] (https://cloud.google.com/compute).
+
+[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
+[![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
+
+[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
+[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
+
+- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
+
+
+
+> Note: This client is a work-in-progress, and may occasionally
+> make backwards-incompatible changes.
+
+Quickstart
+----------
+If you are using Maven, add this to your pom.xml file
+
+If you are using Gradle, add this to your dependencies
+
+If you are using SBT, add this to your dependencies
+
+
+Example Application
+-------------------
+
+
+Authentication
+--------------
+
+See the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) section in the base directory's README.
+
+About Google Cloud Compute
+--------------------------
+
+[Google Cloud Compute][cloud-compute] delivers virtual machines running in Google's innovative data
+centers and worldwide fiber network. Compute Engine's tooling and workflow support enable scaling
+from single instances to global, load-balanced cloud computing. Compute Engine's VMs boot quickly,
+come with persistent disk storage, deliver consistent performance and are available in many
+configurations.
+
+Be sure to activate the Google Cloud Compute API on the Developer's Console to use Compute from
+your project.
+
+See the ``gcloud-java`` API [compute documentation][compute-api] to learn how to interact
+with Google Cloud Compute using this Client Library.
+
+Getting Started
+---------------
+
+
+Troubleshooting
+---------------
+
+To get help, follow the `gcloud-java` links in the `gcloud-*`[shared Troubleshooting document](https://github.com/GoogleCloudPlatform/gcloud-common/blob/master/troubleshooting/readme.md#troubleshooting).
+
+Java Versions
+-------------
+
+Java 7 or above is required for using this client.
+
+Testing
+-------
+
+This library has tools to help make tests for code using Cloud Compute.
+
+See [TESTING] to read more about testing.
+
+Versioning
+----------
+
+This library follows [Semantic Versioning] (http://semver.org/).
+
+It is currently in major version zero (``0.y.z``), which means that anything
+may change at any time and the public API should not be considered
+stable.
+
+Contributing
+------------
+
+Contributions to this library are always welcome and highly encouraged.
+
+See [CONTRIBUTING] for more information on how to get started.
+
+License
+-------
+
+Apache 2.0 - See [LICENSE] for more information.
+
+
+[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md
+[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE
+[TESTING]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md#testing-code-that-uses-compute
+[cloud-platform]: https://cloud.google.com/
+
+[cloud-compute]: https://cloud.google.com/compute/
+[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html
diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml
new file mode 100644
index 000000000000..5bf336e01a2f
--- /dev/null
+++ b/gcloud-java-compute/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+ gcloud-java-compute
+ jar
+ GCloud Java compute
+
+ Java idiomatic client for Google Cloud Compute Engine.
+
+
+ com.google.gcloud
+ gcloud-java-pom
+ 0.1.5-SNAPSHOT
+
+
+ gcloud-java-compute
+
+
+
+ ${project.groupId}
+ gcloud-java-core
+ ${project.version}
+
+
+ com.google.apis
+ google-api-services-compute
+ v1-rev97-1.21.0
+ compile
+
+
+ com.google.guava
+ guava-jdk5
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.easymock
+ easymock
+ 3.4
+ test
+
+
+
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
new file mode 100644
index 000000000000..4576f62f84b9
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
@@ -0,0 +1,27 @@
+/*
+ * 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.Service;
+
+/**
+ * An interface for Google Cloud Compute Engine.
+ *
+ * @see Google Cloud Compute Engine
+ */
+public interface Compute extends Service {
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java
new file mode 100644
index 000000000000..94a409305338
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java
@@ -0,0 +1,59 @@
+/*
+ * 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.common.collect.ImmutableSet;
+import com.google.gcloud.BaseServiceException;
+import com.google.gcloud.RetryHelper.RetryHelperException;
+import com.google.gcloud.RetryHelper.RetryInterruptedException;
+
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * Compute Engine service exception.
+ */
+public class ComputeException extends BaseServiceException {
+
+ private static final Set RETRYABLE_ERRORS = ImmutableSet.of(new Error(500, null));
+ private static final long serialVersionUID = -8039359778707845810L;
+
+ public ComputeException(int code, String message) {
+ super(code, message, null, true);
+ }
+
+ public ComputeException(IOException exception) {
+ super(exception, true);
+ }
+
+ @Override
+ protected Set retryableErrors() {
+ return RETRYABLE_ERRORS;
+ }
+
+ /**
+ * Translate RetryHelperException to the ComputeException that caused the error. This method will
+ * always throw an exception.
+ *
+ * @throws ComputeException when {@code ex} was caused by a {@code ComputeException}
+ * @throws RetryInterruptedException when {@code ex} is a {@code RetryInterruptedException}
+ */
+ static BaseServiceException translateAndThrow(RetryHelperException ex) {
+ BaseServiceException.translateAndPropagateIfPossible(ex);
+ throw new ComputeException(UNKNOWN_CODE, ex.getMessage());
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java
new file mode 100644
index 000000000000..100631eef91d
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java
@@ -0,0 +1,25 @@
+/*
+ * 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.ServiceFactory;
+
+/**
+ * An interface for Compute factories.
+ */
+public interface ComputeFactory extends ServiceFactory {
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
new file mode 100644
index 000000000000..8a3a82af8827
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
@@ -0,0 +1,30 @@
+/*
+ * 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.BaseService;
+import com.google.gcloud.spi.ComputeRpc;
+
+final class ComputeImpl extends BaseService implements Compute {
+
+ private final ComputeRpc computeRpc;
+
+ ComputeImpl(ComputeOptions options) {
+ super(options);
+ computeRpc = options.rpc();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java
new file mode 100644
index 000000000000..9fab138b26b4
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java
@@ -0,0 +1,114 @@
+/*
+ * 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.common.collect.ImmutableSet;
+import com.google.gcloud.ServiceOptions;
+import com.google.gcloud.spi.ComputeRpc;
+import com.google.gcloud.spi.ComputeRpcFactory;
+import com.google.gcloud.spi.DefaultComputeRpc;
+
+import java.util.Set;
+
+public class ComputeOptions extends ServiceOptions {
+
+ private static final String COMPUTE_SCOPE = "https://www.googleapis.com/auth/compute";
+ private static final Set SCOPES = ImmutableSet.of(COMPUTE_SCOPE);
+ private static final long serialVersionUID = 6509557711917342058L;
+
+ public static class DefaultComputeFactory implements ComputeFactory {
+
+ private static final ComputeFactory INSTANCE = new DefaultComputeFactory();
+
+ @Override
+ public Compute create(ComputeOptions options) {
+ return new ComputeImpl(options);
+ }
+ }
+
+ public static class DefaultComputeRpcFactory implements ComputeRpcFactory {
+
+ private static final ComputeRpcFactory INSTANCE = new DefaultComputeRpcFactory();
+
+ @Override
+ public ComputeRpc create(ComputeOptions options) {
+ return new DefaultComputeRpc(options);
+ }
+ }
+
+ public static class Builder extends
+ ServiceOptions.Builder {
+
+ private Builder() {
+ }
+
+ private Builder(ComputeOptions options) {
+ super(options);
+ }
+
+ @Override
+ public ComputeOptions build() {
+ return new ComputeOptions(this);
+ }
+ }
+
+ private ComputeOptions(Builder builder) {
+ super(ComputeFactory.class, ComputeRpcFactory.class, builder);
+ }
+
+ @Override
+ protected ComputeFactory defaultServiceFactory() {
+ return DefaultComputeFactory.INSTANCE;
+ }
+
+ @Override
+ protected ComputeRpcFactory defaultRpcFactory() {
+ return DefaultComputeRpcFactory.INSTANCE;
+ }
+
+ @Override
+ protected Set scopes() {
+ return SCOPES;
+ }
+
+ @Override
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return baseHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ComputeOptions)) {
+ return false;
+ }
+ ComputeOptions other = (ComputeOptions) obj;
+ return baseEquals(other);
+ }
+
+ public static ComputeOptions defaultInstance() {
+ return builder().build();
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java
new file mode 100644
index 000000000000..c80071dde10a
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java
@@ -0,0 +1,172 @@
+/*
+ * 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.common.base.Function;
+import com.google.common.base.MoreObjects;
+
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * The deprecation status associated to a Google Compute Engine resource.
+ *
+ * @param The Google Compute Engine resource to which the deprecation status refers to.
+ */
+public final class DeprecationStatus implements Serializable {
+
+ private static final long serialVersionUID = -2695077634793679794L;
+ private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private final Long deleted;
+ private final Long deprecated;
+ private final Long obsolete;
+ private final T replacement;
+ private final Status status;
+
+ /**
+ * The deprecation status of a Google Compute Engine resource.
+ */
+ public enum Status {
+ /**
+ * Operations that create a Google Compute Engine entity using a deprecated resource will return
+ * successfully but with a warning indicating the deprecation and suggesting a replacement.
+ */
+ DEPRECATED,
+
+ /**
+ * Operations that create a Google Compute Engine entity using an obsolete resource will be
+ * rejected and result in an error.
+ */
+ OBSOLETE,
+
+ /**
+ * Operations that create a Google Compute Engine entity using a deleted resource will be
+ * rejected and result in an error.
+ */
+ DELETED
+ }
+
+ DeprecationStatus(Long deleted, Long deprecated, Long obsolete, T replacement, Status status) {
+ this.deleted = deleted;
+ this.deprecated = deprecated;
+ this.obsolete = obsolete;
+ this.replacement = replacement;
+ this.status = status;
+ }
+
+ /**
+ * Returns the timestamp on or after which the deprecation state of this resource will be changed
+ * to {@link Status#DELETED}. In milliseconds since epoch.
+ */
+ public Long deleted() {
+ return deleted;
+ }
+
+ /**
+ * Returns the timestamp on or after which the deprecation state of this resource will be changed
+ * to {@link Status#DEPRECATED}. In milliseconds since epoch.
+ */
+ public Long deprecated() {
+ return deprecated;
+ }
+
+ /**
+ * Returns the timestamp on or after which the deprecation state of this resource will be changed
+ * to {@link Status#OBSOLETE}. In milliseconds since epoch.
+ */
+ public Long obsolete() {
+ return obsolete;
+ }
+
+ /**
+ * Returns the identity of the suggested replacement for a deprecated resource. The suggested
+ * replacement resource must be the same kind of resource as the deprecated resource.
+ */
+ public T replacement() {
+ return replacement;
+ }
+
+ /**
+ * Returns the deprecation state of this resource.
+ */
+ public Status status() {
+ return status;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("deleted", deleted)
+ .add("deprecated", deprecated)
+ .add("obsolete", obsolete)
+ .add("replacement", replacement)
+ .add("status", status)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(deleted, deprecated, obsolete, replacement, status);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof DeprecationStatus
+ && Objects.equals(toPb(), ((DeprecationStatus) obj).toPb());
+ }
+
+ com.google.api.services.compute.model.DeprecationStatus toPb() {
+ com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb =
+ new com.google.api.services.compute.model.DeprecationStatus();
+ if (deleted != null) {
+ deprecationStatusPb.setDeleted(TIMESTAMP_FORMATTER.print(deleted));
+ }
+ if (deprecated != null) {
+ deprecationStatusPb.setDeprecated(TIMESTAMP_FORMATTER.print(deprecated));
+ }
+ if (obsolete != null) {
+ deprecationStatusPb.setObsolete(TIMESTAMP_FORMATTER.print(obsolete));
+ }
+ if (replacement != null) {
+ deprecationStatusPb.setReplacement(replacement.selfLink());
+ }
+ if (status() != null) {
+ deprecationStatusPb.setState(status.name());
+ }
+ return deprecationStatusPb;
+ }
+
+ static DeprecationStatus fromPb(
+ com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb,
+ Function fromUrl) {
+ return new DeprecationStatus<>(
+ deprecationStatusPb.getDeleted() != null
+ ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeleted()) : null,
+ deprecationStatusPb.getDeprecated() != null
+ ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeprecated()) : null,
+ deprecationStatusPb.getObsolete() != null
+ ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getObsolete()) : null,
+ deprecationStatusPb.getReplacement() != null
+ ? fromUrl.apply(deprecationStatusPb.getReplacement()) : null,
+ deprecationStatusPb.getState() != null
+ ? Status.valueOf(deprecationStatusPb.getState()) : null);
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java
new file mode 100644
index 000000000000..ce57067786c4
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java
@@ -0,0 +1,240 @@
+/*
+ * 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.common.base.Function;
+import com.google.common.base.MoreObjects;
+
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.Objects;
+
+/**
+ * A Google Compute Engine disk type. A disk type represents the type of disk to use, such as
+ * {@code pd-ssd} or {@code pd-standard}.
+ *
+ * @see Disk Types
+ */
+public final class DiskType implements Serializable {
+
+ static final Function FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public DiskType apply(com.google.api.services.compute.model.DiskType pb) {
+ return DiskType.fromPb(pb);
+ }
+ };
+ static final Function TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) {
+ return diskType.toPb();
+ }
+ };
+
+ private static final long serialVersionUID = -944042261695072026L;
+ private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private final String id;
+ private final DiskTypeId diskTypeId;
+ private final Long creationTimestamp;
+ private final String description;
+ private final String validDiskSize;
+ private final Long defaultDiskSizeGb;
+ private final DeprecationStatus deprecationStatus;
+
+ static final class Builder {
+
+ private String id;
+ private DiskTypeId diskTypeId;
+ private Long creationTimestamp;
+ private String description;
+ private String validDiskSize;
+ private Long defaultDiskSizeGb;
+ private DeprecationStatus deprecationStatus;
+
+ private Builder() {}
+
+ Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ Builder creationTimestamp(Long creationTimestamp) {
+ this.creationTimestamp = creationTimestamp;
+ return this;
+ }
+
+ Builder diskTypeId(DiskTypeId diskTypeId) {
+ this.diskTypeId = diskTypeId;
+ return this;
+ }
+
+ Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ Builder validDiskSize(String validDiskSize) {
+ this.validDiskSize = validDiskSize;
+ return this;
+ }
+
+ Builder defaultDiskSizeGb(Long defaultDiskSizeGb) {
+ this.defaultDiskSizeGb = defaultDiskSizeGb;
+ return this;
+ }
+
+ Builder deprecationStatus(DeprecationStatus deprecationStatus) {
+ this.deprecationStatus = deprecationStatus;
+ return this;
+ }
+
+ DiskType build() {
+ return new DiskType(this);
+ }
+ }
+
+ private DiskType(Builder builder) {
+ this.id = builder.id;
+ this.creationTimestamp = builder.creationTimestamp;
+ this.diskTypeId = builder.diskTypeId;
+ this.description = builder.description;
+ this.validDiskSize = builder.validDiskSize;
+ this.defaultDiskSizeGb = builder.defaultDiskSizeGb;
+ this.deprecationStatus = builder.deprecationStatus;
+ }
+
+ /**
+ * Returns the creation timestamp in milliseconds since epoch.
+ */
+ public Long creationTimestamp() {
+ return creationTimestamp;
+ }
+
+ /**
+ * Returns the disk type's identity.
+ */
+ public DiskTypeId diskTypeId() {
+ return diskTypeId;
+ }
+
+ /**
+ * Returns an unique identifier for the disk type; defined by the service.
+ */
+ public String id() {
+ return id;
+ }
+
+ /**
+ * Returns a textual description of the disk type.
+ */
+ public String description() {
+ return description;
+ }
+
+ /**
+ * Returns an optional textual description of the valid disk size, such as "10GB-10TB".
+ */
+ public String validDiskSize() {
+ return validDiskSize;
+ }
+
+ /**
+ * Returns the service-defined default disk size in GB.
+ */
+ public Long defaultDiskSizeGb() {
+ return defaultDiskSizeGb;
+ }
+
+ /**
+ * Returns the deprecation status of the disk type. If {@link DeprecationStatus#status()} is
+ * either {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE}
+ * the disk type should not be used. Returns {@code null} if the disk type is not deprecated.
+ */
+ public DeprecationStatus deprecationStatus() {
+ return deprecationStatus;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("id", id)
+ .add("creationTimestamp", creationTimestamp)
+ .add("description", description)
+ .add("validDiskSize", validDiskSize)
+ .add("defaultDiskSizeGb", defaultDiskSizeGb)
+ .add("deprecationStatus", deprecationStatus)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(diskTypeId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof DiskType && Objects.equals(toPb(), ((DiskType) obj).toPb());
+ }
+
+ com.google.api.services.compute.model.DiskType toPb() {
+ com.google.api.services.compute.model.DiskType diskTypePb =
+ new com.google.api.services.compute.model.DiskType();
+ if (id != null) {
+ diskTypePb.setId(new BigInteger(id));
+ }
+ if (creationTimestamp != null) {
+ diskTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp));
+ }
+ diskTypePb.setDescription(description);
+ diskTypePb.setValidDiskSize(validDiskSize);
+ diskTypePb.setSelfLink(diskTypeId.selfLink());
+ diskTypePb.setDefaultDiskSizeGb(defaultDiskSizeGb);
+ diskTypePb.setZone(diskTypeId.zoneId().selfLink());
+ if (deprecationStatus != null) {
+ diskTypePb.setDeprecated(deprecationStatus.toPb());
+ }
+ return diskTypePb;
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+
+ static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb) {
+ Builder builder = builder();
+ if (diskTypePb.getId() != null) {
+ builder.id(diskTypePb.getId().toString());
+ }
+ if (diskTypePb.getCreationTimestamp() != null) {
+ builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(diskTypePb.getCreationTimestamp()));
+ }
+ builder.diskTypeId(DiskTypeId.fromUrl(diskTypePb.getSelfLink()));
+ builder.description(diskTypePb.getDescription());
+ builder.validDiskSize(diskTypePb.getValidDiskSize());
+ builder.defaultDiskSizeGb(diskTypePb.getDefaultDiskSizeGb());
+ if (diskTypePb.getDeprecated() != null) {
+ builder.deprecationStatus(
+ DeprecationStatus.fromPb(diskTypePb.getDeprecated(), DiskTypeId.FROM_URL_FUNCTION));
+ }
+ return builder.build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java
new file mode 100644
index 000000000000..cdf1fd42eedc
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java
@@ -0,0 +1,130 @@
+/*
+ * 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.common.base.Function;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Identity for a Google Compute Engine disk type.
+ */
+public final class DiskTypeId extends ZoneResourceId {
+
+ static final Function FROM_URL_FUNCTION = new Function() {
+ @Override
+ public DiskTypeId apply(String pb) {
+ return DiskTypeId.fromUrl(pb);
+ }
+ };
+ static final Function TO_URL_FUNCTION = new Function() {
+ @Override
+ public String apply(DiskTypeId diskTypeId) {
+ return diskTypeId.selfLink();
+ }
+ };
+
+ private static final String REGEX = ZoneResourceId.REGEX + "diskTypes/([^/]+)";
+ private static final Pattern PATTERN = Pattern.compile(REGEX);
+ private static final long serialVersionUID = 7337881474103686219L;
+
+ private final String diskType;
+
+ private DiskTypeId(String project, String zone, String diskType) {
+ super(project, zone);
+ this.diskType = checkNotNull(diskType);
+ }
+
+ /**
+ * Returns the name of the disk type.
+ */
+ public String diskType() {
+ return diskType;
+ }
+
+ @Override
+ public String selfLink() {
+ return super.selfLink() + "/diskTypes/" + diskType;
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("diskType", diskType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.baseHashCode(), diskType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof DiskTypeId
+ && baseEquals((DiskTypeId) obj)
+ && Objects.equals(diskType, ((DiskTypeId) obj).diskType);
+ }
+
+ @Override
+ DiskTypeId setProjectId(String projectId) {
+ if (project() != null) {
+ return this;
+ }
+ return DiskTypeId.of(projectId, zone(), diskType);
+ }
+
+ /**
+ * Returns a disk type identity given the zone identity and the disk type name.
+ */
+ public static DiskTypeId of(ZoneId zoneId, String diskType) {
+ return new DiskTypeId(zoneId.project(), zoneId.zone(), diskType);
+ }
+
+ /**
+ * Returns a disk type identity given the zone and disk type names.
+ */
+ public static DiskTypeId of(String zone, String diskType) {
+ return of(ZoneId.of(null, zone), diskType);
+ }
+
+ /**
+ * Returns a disk type identity given project disk, zone and disk type names.
+ */
+ public static DiskTypeId of(String project, String zone, String diskType) {
+ return of(ZoneId.of(project, zone), diskType);
+ }
+
+ /**
+ * Returns {@code true} if the provided string matches the expected format of a disk type URL.
+ * Returns {@code false} otherwise.
+ */
+ static boolean matchesUrl(String url) {
+ return PATTERN.matcher(url).matches();
+ }
+
+ static DiskTypeId fromUrl(String url) {
+ Matcher matcher = PATTERN.matcher(url);
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException(url + " is not a valid disk type URL");
+ }
+ return DiskTypeId.of(matcher.group(1), matcher.group(2), matcher.group(3));
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java
new file mode 100644
index 000000000000..2c6cb4ac9422
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java
@@ -0,0 +1,89 @@
+/*
+ * 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.common.base.MoreObjects;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * A Google Compute Engine License. A License represents a software license. Licenses are used to
+ * track software usage in images, persistent disks, snapshots, and virtual machine instances.
+ *
+ * @see Licenses
+ */
+public final class License implements Serializable {
+
+ private static final long serialVersionUID = 6907923910319640363L;
+
+ private final LicenseId licenseId;
+ private final Boolean chargesUseFee;
+
+ License(LicenseId licenseId, Boolean chargesUseFee) {
+ this.licenseId = checkNotNull(licenseId);
+ this.chargesUseFee = chargesUseFee;
+ }
+
+ /**
+ * Returns the identity of the license.
+ */
+ public LicenseId licenseId() {
+ return licenseId;
+ }
+
+ /**
+ * Returns {@code true} if the customer will be charged a license fee for running software that
+ * contains this license on an instance.
+ */
+ public Boolean chargesUseFee() {
+ return chargesUseFee;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("licenseId", licenseId)
+ .add("chargesUseFee", chargesUseFee)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(licenseId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof License && Objects.equals(toPb(), ((License) obj).toPb());
+ }
+
+ com.google.api.services.compute.model.License toPb() {
+ com.google.api.services.compute.model.License licensePb =
+ new com.google.api.services.compute.model.License();
+ licensePb.setName(licenseId.license());
+ licensePb.setChargesUseFee(chargesUseFee);
+ licensePb.setSelfLink(licenseId.selfLink());
+ return licensePb;
+ }
+
+ static License fromPb(com.google.api.services.compute.model.License licensePb) {
+ return new License(LicenseId.fromUrl(licensePb.getSelfLink()), licensePb.getChargesUseFee());
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java
new file mode 100644
index 000000000000..36d3037bc41b
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java
@@ -0,0 +1,123 @@
+/*
+ * 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.common.base.Function;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Identity for a Google Compute Engine license.
+ */
+public final class LicenseId extends ResourceId {
+
+ static final Function FROM_URL_FUNCTION = new Function() {
+ @Override
+ public LicenseId apply(String pb) {
+ return LicenseId.fromUrl(pb);
+ }
+ };
+ static final Function TO_URL_FUNCTION = new Function() {
+ @Override
+ public String apply(LicenseId licenseId) {
+ return licenseId.selfLink();
+ }
+ };
+
+ private static final String REGEX = ResourceId.REGEX + "global/licenses/([^/]+)";
+ private static final Pattern PATTERN = Pattern.compile(REGEX);
+ private static final long serialVersionUID = -2239484554024469651L;
+
+ private final String license;
+
+ private LicenseId(String project, String license) {
+ super(project);
+ this.license = checkNotNull(license);
+ }
+
+ /**
+ * Returns the name of the license.
+ */
+ public String license() {
+ return license;
+ }
+
+ @Override
+ public String selfLink() {
+ return super.selfLink() + "/global/licenses/" + license;
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("license", license);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(baseHashCode(), license);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof LicenseId
+ && baseEquals((LicenseId) obj)
+ && Objects.equals(license, ((LicenseId) obj).license);
+ }
+
+ @Override
+ LicenseId setProjectId(String projectId) {
+ if (project() != null) {
+ return this;
+ }
+ return LicenseId.of(projectId, license);
+ }
+
+ /**
+ * Returns a license identity given the license name.
+ */
+ public static LicenseId of(String license) {
+ return new LicenseId(null, license);
+ }
+
+ /**
+ * Returns a license identity given project and license names.
+ */
+ public static LicenseId of(String project, String license) {
+ return new LicenseId(project, license);
+ }
+
+ /**
+ * Returns {@code true} if the provided string matches the expected format of a license URL.
+ * Returns {@code false} otherwise.
+ */
+ static boolean matchesUrl(String url) {
+ return PATTERN.matcher(url).matches();
+ }
+
+ static LicenseId fromUrl(String url) {
+ Matcher matcher = PATTERN.matcher(url);
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException(url + " is not a valid license URL");
+ }
+ return LicenseId.of(matcher.group(1), matcher.group(2));
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java
new file mode 100644
index 000000000000..ee242c0d1ef0
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java
@@ -0,0 +1,320 @@
+/*
+ * 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.MachineType.ScratchDisks;
+import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+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 machine type. A machine type determine the virtualized hardware
+ * specifications of your virtual machine instances, such as the amount of memory or number of
+ * virtual CPUs.
+ *
+ * @see Machine Types
+ */
+public final class MachineType implements Serializable {
+
+ static final Function
+ FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public MachineType apply(com.google.api.services.compute.model.MachineType pb) {
+ return MachineType.fromPb(pb);
+ }
+ };
+ static final Function
+ TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public com.google.api.services.compute.model.MachineType apply(MachineType type) {
+ return type.toPb();
+ }
+ };
+ private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private static final long serialVersionUID = -4210962597502860450L;
+
+ private final MachineTypeId machineTypeId;
+ private final String id;
+ private final Long creationTimestamp;
+ private final String description;
+ private final Integer cpus;
+ private final Integer memoryMb;
+ private final List scratchDisksSizeGb;
+ private final Integer maximumPersistentDisks;
+ private final Long maximumPersistentDisksSizeGb;
+ private final DeprecationStatus deprecationStatus;
+
+ static final class Builder {
+
+ private MachineTypeId machineTypeId;
+ private String id;
+ private Long creationTimestamp;
+ private String description;
+ private Integer cpus;
+ private Integer memoryMb;
+ private List scratchDisksSizeGb;
+ private Integer maximumPersistentDisks;
+ private Long maximumPersistentDisksSizeGb;
+ private DeprecationStatus deprecationStatus;
+
+ private Builder() {}
+
+ Builder machineTypeId(MachineTypeId machineTypeId) {
+ this.machineTypeId = machineTypeId;
+ return this;
+ }
+
+ Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ Builder creationTimestamp(Long creationTimestamp) {
+ this.creationTimestamp = creationTimestamp;
+ return this;
+ }
+
+ Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ Builder cpus(Integer cpus) {
+ this.cpus = cpus;
+ return this;
+ }
+
+ Builder memoryMb(Integer memoryMb) {
+ this.memoryMb = memoryMb;
+ return this;
+ }
+
+ Builder scratchDisksSizeGb(List scratchDisksSizeGb) {
+ this.scratchDisksSizeGb = scratchDisksSizeGb;
+ return this;
+ }
+
+ Builder maximumPersistentDisks(Integer maximumPersistentDisks) {
+ this.maximumPersistentDisks = maximumPersistentDisks;
+ return this;
+ }
+
+ Builder maximumPersistentDisksSizeGb(Long maximumPersistentDisksSizeGb) {
+ this.maximumPersistentDisksSizeGb = maximumPersistentDisksSizeGb;
+ return this;
+ }
+
+ Builder deprecationStatus(DeprecationStatus deprecationStatus) {
+ this.deprecationStatus = deprecationStatus;
+ return this;
+ }
+
+ MachineType build() {
+ return new MachineType(this);
+ }
+ }
+
+ private MachineType(Builder builder) {
+ this.machineTypeId = builder.machineTypeId;
+ this.id = builder.id;
+ this.creationTimestamp = builder.creationTimestamp;
+ this.description = builder.description;
+ this.cpus = builder.cpus;
+ this.memoryMb = builder.memoryMb;
+ this.scratchDisksSizeGb = builder.scratchDisksSizeGb;
+ this.maximumPersistentDisks = builder.maximumPersistentDisks;
+ this.maximumPersistentDisksSizeGb = builder.maximumPersistentDisksSizeGb;
+ this.deprecationStatus = builder.deprecationStatus;
+ }
+
+ /**
+ * Returns the machine type's identity.
+ */
+ public MachineTypeId machineTypeId() {
+ return machineTypeId;
+ }
+
+ /**
+ * Returns an unique identifier for the machine type; defined by the service.
+ */
+ public String id() {
+ return id;
+ }
+
+ /**
+ * Returns the creation timestamp in milliseconds since epoch.
+ */
+ public Long creationTimestamp() {
+ return creationTimestamp;
+ }
+
+ /**
+ * Returns an optional textual description of the machine type.
+ */
+ public String description() {
+ return description;
+ }
+
+ /**
+ * Returns the number of virtual CPUs that are available to the instance.
+ */
+ public Integer cpus() {
+ return cpus;
+ }
+
+ /**
+ * Returns the amount of physical memory available to the instance, defined in MB.
+ */
+ public Integer memoryMb() {
+ return memoryMb;
+ }
+
+ /**
+ * Returns the size of all extended scratch disks assigned to the instance, defined in GB.
+ */
+ public List scratchDisksSizeGb() {
+ return scratchDisksSizeGb;
+ }
+
+ /**
+ * Returns the maximum number of persistent disks allowed by this instance type.
+ */
+ public Integer maximumPersistentDisks() {
+ return maximumPersistentDisks;
+ }
+
+ /**
+ * Returns the maximum total persistent disks size allowed, defined in GB.
+ */
+ public Long maximumPersistentDisksSizeGb() {
+ return maximumPersistentDisksSizeGb;
+ }
+
+ /**
+ * Returns the deprecation status of the machine type. If {@link DeprecationStatus#status()} is
+ * either {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE}
+ * the machine type should not be used. Returns {@code null} if the machine type is not
+ * deprecated.
+ */
+ public DeprecationStatus deprecationStatus() {
+ return deprecationStatus;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("machineTypeId", machineTypeId)
+ .add("id", id)
+ .add("creationTimestamp", creationTimestamp)
+ .add("description", description)
+ .add("cpus", cpus)
+ .add("memoryMb", memoryMb)
+ .add("scratchDisksSizeGb", scratchDisksSizeGb)
+ .add("maximumPersistentDisks", maximumPersistentDisks)
+ .add("maximumPersistentDisksSizeGb", maximumPersistentDisksSizeGb)
+ .add("deprecationStatus", deprecationStatus)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(machineTypeId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof MachineType && Objects.equals(toPb(), ((MachineType) obj).toPb());
+ }
+
+ com.google.api.services.compute.model.MachineType toPb() {
+ com.google.api.services.compute.model.MachineType machineTypePb =
+ new com.google.api.services.compute.model.MachineType();
+ if (id != null) {
+ machineTypePb.setId(new BigInteger(id));
+ }
+ if (creationTimestamp != null) {
+ machineTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp));
+ }
+ machineTypePb.setName(machineTypeId.machineType());
+ machineTypePb.setDescription(description);
+ machineTypePb.setSelfLink(machineTypeId.selfLink());
+ machineTypePb.setGuestCpus(cpus);
+ machineTypePb.setMemoryMb(memoryMb);
+ if (scratchDisksSizeGb != null) {
+ machineTypePb.setScratchDisks(Lists.transform(scratchDisksSizeGb,
+ new Function() {
+ @Override
+ public ScratchDisks apply(Integer diskSize) {
+ return new ScratchDisks().setDiskGb(diskSize);
+ }
+ }));
+ }
+ machineTypePb.setMaximumPersistentDisks(maximumPersistentDisks);
+ machineTypePb.setMaximumPersistentDisksSizeGb(maximumPersistentDisksSizeGb);
+ machineTypePb.setZone(machineTypeId.zoneId().zone());
+ if (deprecationStatus != null) {
+ machineTypePb.setDeprecated(deprecationStatus.toPb());
+ }
+ return machineTypePb;
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+
+ static MachineType fromPb(com.google.api.services.compute.model.MachineType machineTypePb) {
+ Builder builder = builder();
+ builder.machineTypeId(MachineTypeId.fromUrl(machineTypePb.getSelfLink()));
+ if (machineTypePb.getId() != null) {
+ builder.id(machineTypePb.getId().toString());
+ }
+ if (machineTypePb.getCreationTimestamp() != null) {
+ builder.creationTimestamp(
+ TIMESTAMP_FORMATTER.parseMillis(machineTypePb.getCreationTimestamp()));
+ }
+ builder.description(machineTypePb.getDescription());
+ builder.cpus(machineTypePb.getGuestCpus());
+ builder.memoryMb(machineTypePb.getMemoryMb());
+ if (machineTypePb.getScratchDisks() != null) {
+ builder.scratchDisksSizeGb(
+ Lists.transform(machineTypePb.getScratchDisks(), new Function() {
+ @Override
+ public Integer apply(ScratchDisks scratchDiskPb) {
+ return scratchDiskPb.getDiskGb();
+ }
+ }));
+ }
+ builder.maximumPersistentDisks(machineTypePb.getMaximumPersistentDisks());
+ builder.maximumPersistentDisksSizeGb(machineTypePb.getMaximumPersistentDisksSizeGb());
+ if (machineTypePb.getDeprecated() != null) {
+ builder.deprecationStatus(
+ DeprecationStatus.fromPb(machineTypePb.getDeprecated(), MachineTypeId.FROM_URL_FUNCTION));
+ }
+ return builder.build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java
new file mode 100644
index 000000000000..1252719e05d7
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java
@@ -0,0 +1,125 @@
+/*
+ * 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.common.base.Function;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Identity for a Google Compute Engine machine type.
+ */
+public final class MachineTypeId extends ZoneResourceId {
+
+ static final Function FROM_URL_FUNCTION =
+ new Function() {
+ @Override
+ public MachineTypeId apply(String pb) {
+ return MachineTypeId.fromUrl(pb);
+ }
+ };
+ static final Function TO_URL_FUNCTION =
+ new Function() {
+ @Override
+ public String apply(MachineTypeId machineTypeId) {
+ return machineTypeId.selfLink();
+ }
+ };
+
+ private static final String REGEX = ZoneResourceId.REGEX + "machineTypes/([^/]+)";
+ private static final Pattern PATTERN = Pattern.compile(REGEX);
+ private static final long serialVersionUID = -5819598544478859608L;
+
+ private final String machineType;
+
+ private MachineTypeId(String project, String zone, String machineType) {
+ super(project, zone);
+ this.machineType = checkNotNull(machineType);
+ }
+
+ /**
+ * Returns the name of the machine type.
+ */
+ public String machineType() {
+ return machineType;
+ }
+
+ @Override
+ public String selfLink() {
+ return super.selfLink() + "/machineTypes/" + machineType;
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("machineType", machineType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(baseHashCode(), machineType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof MachineTypeId
+ && baseEquals((MachineTypeId) obj)
+ && Objects.equals(machineType, ((MachineTypeId) obj).machineType);
+ }
+
+ @Override
+ MachineTypeId setProjectId(String projectId) {
+ if (project() != null) {
+ return this;
+ }
+ return MachineTypeId.of(projectId, zone(), machineType);
+ }
+
+ /**
+ * Returns a machine type identity given the zone and type names.
+ */
+ public static MachineTypeId of(String zone, String machineType) {
+ return new MachineTypeId(null, zone, machineType);
+ }
+
+ /**
+ * Returns a machine type identity given project, zone and type names.
+ */
+ public static MachineTypeId of(String project, String zone, String machineType) {
+ return new MachineTypeId(project, zone, machineType);
+ }
+
+ /**
+ * Returns {@code true} if the provided string matches the expected format of a machine type URL.
+ * Returns {@code false} otherwise.
+ */
+ static boolean matchesUrl(String url) {
+ return PATTERN.matcher(url).matches();
+ }
+
+ static MachineTypeId fromUrl(String url) {
+ Matcher matcher = PATTERN.matcher(url);
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException(url + " is not a valid machine type URL");
+ }
+ return MachineTypeId.of(matcher.group(1), matcher.group(2), matcher.group(3));
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java
new file mode 100644
index 000000000000..38f79a691721
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java
@@ -0,0 +1,374 @@
+/*
+ * 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.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 region.
+ *
+ * @see Region and Zones
+ */
+public final class Region implements Serializable {
+
+ static final Function FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public Region apply(com.google.api.services.compute.model.Region pb) {
+ return Region.fromPb(pb);
+ }
+ };
+ static final Function TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public com.google.api.services.compute.model.Region apply(Region region) {
+ return region.toPb();
+ }
+ };
+
+ private static final long serialVersionUID = -3578710133393645135L;
+ private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private final RegionId regionId;
+ private final String id;
+ private final Long creationTimestamp;
+ private final String description;
+ private final Status status;
+ private final List zones;
+ private final List quotas;
+ private final DeprecationStatus deprecationStatus;
+
+ /**
+ * Status of the region.
+ */
+ public enum Status {
+ UP,
+ DOWN
+ }
+
+ /**
+ * A quota assigned to this region.
+ */
+ public static final class Quota implements Serializable {
+
+ static final Function FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public Quota apply(com.google.api.services.compute.model.Quota pb) {
+ return Quota.fromPb(pb);
+ }
+ };
+ static final Function TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public com.google.api.services.compute.model.Quota apply(Quota quota) {
+ return quota.toPb();
+ }
+ };
+ private static final long serialVersionUID = -4357118665133226338L;
+
+ private final String metric;
+ private final double limit;
+ private final double usage;
+
+ /**
+ * Returns a region quota object.
+ */
+ Quota(String metric, double limit, double usage) {
+ this.metric = metric;
+ this.limit = limit;
+ this.usage = usage;
+ }
+
+ /**
+ * Returns the name of the quota metric.
+ */
+ public String metric() {
+ return metric;
+ }
+
+ /**
+ * Returns the quota limit for this metric.
+ */
+ public double limit() {
+ return limit;
+ }
+
+ /**
+ * Returns the current usage for this quota.
+ */
+ public double usage() {
+ return usage;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("metric", metric)
+ .add("limit", limit)
+ .add("usage", usage)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(metric, limit, usage);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Quota)) {
+ return false;
+ }
+ Quota other = (Quota) obj;
+ return Objects.equals(metric, other.metric)
+ && Objects.equals(limit, other.limit)
+ && Objects.equals(usage, other.usage);
+ }
+
+ com.google.api.services.compute.model.Quota toPb() {
+ return new com.google.api.services.compute.model.Quota()
+ .setMetric(metric)
+ .setLimit(limit)
+ .setUsage(usage);
+ }
+
+ static Quota fromPb(com.google.api.services.compute.model.Quota quotaPb) {
+ return new Quota(quotaPb.getMetric(), quotaPb.getLimit(), quotaPb.getUsage());
+ }
+ }
+
+ static final class Builder {
+
+ private RegionId regionId;
+ private String id;
+ private Long creationTimestamp;
+ private String description;
+
+ private Status status;
+ private List zones;
+ private List quotas;
+ private DeprecationStatus deprecationStatus;
+
+ private Builder() {}
+
+ Builder regionId(RegionId regionId) {
+ this.regionId = regionId;
+ return this;
+ }
+
+ Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ Builder creationTimestamp(Long creationTimestamp) {
+ this.creationTimestamp = creationTimestamp;
+ return this;
+ }
+
+ Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ Builder status(Status status) {
+ this.status = status;
+ return this;
+ }
+
+ Builder zones(List zones) {
+ this.zones = ImmutableList.copyOf(zones);
+ return this;
+ }
+
+ Builder quotas(List quotas) {
+ this.quotas = ImmutableList.copyOf(quotas);
+ return this;
+ }
+
+ Builder deprecationStatus(DeprecationStatus deprecationStatus) {
+ this.deprecationStatus = deprecationStatus;
+ return this;
+ }
+
+ Region build() {
+ return new Region(this);
+ }
+ }
+
+ private Region(Builder builder) {
+ this.regionId = builder.regionId;
+ this.id = builder.id;
+ this.creationTimestamp = builder.creationTimestamp;
+ this.description = builder.description;
+ this.status = builder.status;
+ this.zones = builder.zones;
+ this.quotas = builder.quotas;
+ this.deprecationStatus = builder.deprecationStatus;
+ }
+
+ /**
+ * Returns the region's identity.
+ */
+ public RegionId regionId() {
+ return regionId;
+ }
+
+ /**
+ * Returns an unique identifier for the region; defined by the service.
+ */
+ public String id() {
+ return id;
+ }
+
+ /**
+ * Returns the creation timestamp in milliseconds since epoch.
+ */
+ public Long creationTimestamp() {
+ return creationTimestamp;
+ }
+
+ /**
+ * Returns an optional textual description of the region.
+ */
+ public String description() {
+ return description;
+ }
+
+ /**
+ * Returns the status of the status.
+ */
+ public Status status() {
+ return status;
+ }
+
+ /**
+ * Returns a list of identities of zones available in this region.
+ */
+ public List zones() {
+ return zones;
+ }
+
+ /**
+ * Returns quotas assigned to this region.
+ */
+ public List quotas() {
+ return quotas;
+ }
+
+ /**
+ * Returns the deprecation status of the region. If {@link DeprecationStatus#status()} is either
+ * {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} the
+ * region should not be used. Returns {@code null} if the region is not deprecated.
+ */
+ public DeprecationStatus deprecationStatus() {
+ return deprecationStatus;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("regionId", regionId)
+ .add("id", id)
+ .add("creationTimestamp", creationTimestamp)
+ .add("description", description)
+ .add("status", status)
+ .add("zones", zones)
+ .add("quotas", quotas)
+ .add("deprecationStatus", deprecationStatus)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(regionId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof Region && Objects.equals(toPb(), ((Region) obj).toPb());
+ }
+
+ com.google.api.services.compute.model.Region toPb() {
+ com.google.api.services.compute.model.Region regionPb =
+ new com.google.api.services.compute.model.Region();
+ if (id != null) {
+ regionPb.setId(new BigInteger(id));
+ }
+ if (creationTimestamp != null) {
+ regionPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp));
+ }
+ regionPb.setName(regionId.region());
+ regionPb.setDescription(description);
+ regionPb.setSelfLink(regionId.selfLink());
+ if (status != null) {
+ regionPb.setStatus(status.name());
+ }
+ if (zones != null) {
+ regionPb.setZones(Lists.transform(zones, ZoneId.TO_URL_FUNCTION));
+ }
+ if (quotas != null) {
+ regionPb.setQuotas(Lists.transform(quotas, Quota.TO_PB_FUNCTION));
+ }
+ if (deprecationStatus != null) {
+ regionPb.setDeprecated(deprecationStatus.toPb());
+ }
+ return regionPb;
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+
+ static Region fromPb(com.google.api.services.compute.model.Region regionPb) {
+ Builder builder = builder();
+ builder.regionId(RegionId.fromUrl(regionPb.getSelfLink()));
+ if (regionPb.getId() != null) {
+ builder.id(regionPb.getId().toString());
+ }
+ if (regionPb.getCreationTimestamp() != null) {
+ builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(regionPb.getCreationTimestamp()));
+ }
+ builder.description(regionPb.getDescription());
+ if (regionPb.getStatus() != null) {
+ builder.status(Status.valueOf(regionPb.getStatus()));
+ }
+ if (regionPb.getZones() != null) {
+ builder.zones(Lists.transform(regionPb.getZones(), ZoneId.FROM_URL_FUNCTION));
+ }
+ if (regionPb.getQuotas() != null) {
+ builder.quotas(Lists.transform(regionPb.getQuotas(), Quota.FROM_PB_FUNCTION));
+ }
+ if (regionPb.getDeprecated() != null) {
+ builder.deprecationStatus(
+ DeprecationStatus.fromPb(regionPb.getDeprecated(), RegionId.FROM_URL_FUNCTION));
+ }
+ return builder.build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java
new file mode 100644
index 000000000000..403edd47ce48
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java
@@ -0,0 +1,128 @@
+/*
+ * 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.common.base.Function;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A Google Compute Engine region identity.
+ */
+public final class RegionId extends ResourceId {
+
+ static final Function FROM_URL_FUNCTION = new Function() {
+ @Override
+ public RegionId apply(String pb) {
+ return RegionId.fromUrl(pb);
+ }
+ };
+ static final Function TO_URL_FUNCTION = new Function() {
+ @Override
+ public String apply(RegionId regionId) {
+ return regionId.selfLink();
+ }
+ };
+
+ private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)";
+ private static final Pattern PATTERN = Pattern.compile(REGEX);
+ private static final long serialVersionUID = 5569092266957249294L;
+
+ private final String region;
+
+ private RegionId(String project, String region) {
+ super(project);
+ this.region = checkNotNull(region);
+ }
+
+ private RegionId(RegionId regionId) {
+ super(regionId.project());
+ this.region = checkNotNull(regionId.region());
+ }
+
+ /**
+ * Returns the name of the region.
+ */
+ public final String region() {
+ return region;
+ }
+
+ @Override
+ public String selfLink() {
+ return super.selfLink() + "/regions/" + region;
+ }
+
+ @Override
+ ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("region", region);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(baseHashCode(), region);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof RegionId
+ && baseEquals((RegionId) obj)
+ && Objects.equals(region, ((RegionId) obj).region);
+ }
+
+ @Override
+ RegionId setProjectId(String projectId) {
+ if (project() != null) {
+ return this;
+ }
+ return RegionId.of(projectId, region);
+ }
+
+ /**
+ * Returns a new region identity given project and region names.
+ */
+ public static RegionId of(String project, String region) {
+ return new RegionId(project, region);
+ }
+
+ /**
+ * Returns a new region identity given region name.
+ */
+ public static RegionId of(String region) {
+ return RegionId.of(null, region);
+ }
+
+ /**
+ * Returns {@code true} if the provided string matches the expected format of a region URL.
+ * Returns {@code false} otherwise.
+ */
+ static boolean matchesUrl(String url) {
+ return PATTERN.matcher(url).matches();
+ }
+
+ static RegionId fromUrl(String url) {
+ Matcher matcher = PATTERN.matcher(url);
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException(url + " is not a valid region URL");
+ }
+ return RegionId.of(matcher.group(1), matcher.group(2));
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java
new file mode 100644
index 000000000000..eeb288b07be1
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java
@@ -0,0 +1,80 @@
+/*
+ * 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.common.base.MoreObjects.ToStringHelper;
+
+import java.util.Objects;
+
+/**
+ * A base class for the identity of Google Compute Engine resources that live in a region.
+ */
+public abstract class RegionResourceId extends ResourceId {
+
+ static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/";
+ private static final long serialVersionUID = 5569092266957249294L;
+
+ private final String region;
+
+ RegionResourceId(String project, String region) {
+ super(project);
+ this.region = checkNotNull(region);
+ }
+
+ RegionResourceId(RegionId regionId) {
+ super(regionId.project());
+ this.region = checkNotNull(regionId.region());
+ }
+
+ /**
+ * Returns the name of the region this resource belongs to.
+ */
+ public final String region() {
+ return region;
+ }
+
+ /**
+ * Returns the identity of the region this resource belongs to.
+ */
+ public final RegionId regionId() {
+ return RegionId.of(project(), region);
+ }
+
+ @Override
+ public String selfLink() {
+ return super.selfLink() + "/regions/" + region;
+ }
+
+ @Override
+ ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("region", region);
+ }
+
+ @Override
+ final int baseHashCode() {
+ return Objects.hash(super.baseHashCode(), region);
+ }
+
+ @Override
+ final boolean baseEquals(ResourceId resourceId) {
+ return resourceId instanceof RegionResourceId
+ && super.baseEquals(resourceId)
+ && Objects.equals(region, ((RegionResourceId) resourceId).region);
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java
new file mode 100644
index 000000000000..38e0fe576ac8
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java
@@ -0,0 +1,71 @@
+/*
+ * 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.common.base.MoreObjects;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Base class for Google Compute Engine resource identities.
+ */
+public abstract class ResourceId implements Serializable {
+
+ static final String REGEX = ".*?projects/([^/]+)/";
+ private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects/";
+ private static final long serialVersionUID = -8028734746870421573L;
+
+ private final String project;
+
+ ResourceId(String project) {
+ this.project = project;
+ }
+
+ /**
+ * Returns a fully qualified URL to the entity.
+ */
+ public String selfLink() {
+ return BASE_URL + project;
+ }
+
+ /**
+ * Returns the name of the project.
+ */
+ public final String project() {
+ return project;
+ }
+
+ MoreObjects.ToStringHelper toStringHelper() {
+ return MoreObjects.toStringHelper(this).add("project", project);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper().toString();
+ }
+
+ int baseHashCode() {
+ return Objects.hash(project);
+ }
+
+ boolean baseEquals(ResourceId resourceId) {
+ return Objects.equals(project, resourceId.project);
+ }
+
+ abstract ResourceId setProjectId(String projectId);
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java
new file mode 100644
index 000000000000..20c64946d7ce
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java
@@ -0,0 +1,395 @@
+/*
+ * 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.Zone.MaintenanceWindows;
+import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+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 zone.
+ *
+ * @see Region and Zones
+ */
+public final class Zone implements Serializable {
+
+ static final Function FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public Zone apply(com.google.api.services.compute.model.Zone pb) {
+ return Zone.fromPb(pb);
+ }
+ };
+ static final Function TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public com.google.api.services.compute.model.Zone apply(Zone region) {
+ return region.toPb();
+ }
+ };
+
+ private static final long serialVersionUID = 6113636504417213010L;
+ private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private final ZoneId zoneId;
+ private final String id;
+ private final Long creationTimestamp;
+ private final String description;
+ private final Status status;
+ private final List maintenanceWindows;
+ private final RegionId region;
+ private final DeprecationStatus deprecationStatus;
+
+ /**
+ * Status of the region.
+ */
+ public enum Status {
+ UP,
+ DOWN
+ }
+
+ /**
+ * A scheduled maintenance windows for this zone. When a zone is in a maintenance window, all
+ * resources which reside in the zone will be unavailable.
+ *
+ * @see Maintenance
+ * Windows
+ */
+ public static final class MaintenanceWindow implements Serializable {
+
+ static final Function FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public MaintenanceWindow apply(MaintenanceWindows pb) {
+ return MaintenanceWindow.fromPb(pb);
+ }
+ };
+ static final Function TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public MaintenanceWindows apply(MaintenanceWindow maintenanceWindow) {
+ return maintenanceWindow.toPb();
+ }
+ };
+
+ private static final long serialVersionUID = 2270641266683329963L;
+
+ private final String name;
+ private final String description;
+ private final Long beginTime;
+ private final Long endTime;
+
+ /**
+ * Returns a zone maintenance window object.
+ */
+ MaintenanceWindow(String name, String description, Long beginTime, Long endTime) {
+ this.name = name;
+ this.description = description;
+ this.beginTime = beginTime;
+ this.endTime = endTime;
+ }
+
+ /**
+ * Returns the name of the maintenance window.
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns a textual description of the maintenance window.
+ */
+ public String description() {
+ return description;
+ }
+
+ /**
+ * Returns the starting time of the maintenance window in milliseconds since epoch.
+ */
+ public Long beginTime() {
+ return beginTime;
+ }
+
+ /**
+ * Returns the ending time of the maintenance window in milliseconds since epoch.
+ */
+ public Long endTime() {
+ return endTime;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("disk", name)
+ .add("description", description)
+ .add("beginTime", beginTime)
+ .add("endTime", endTime)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, description, beginTime, endTime);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof MaintenanceWindow
+ && Objects.equals(toPb(), ((MaintenanceWindow) obj).toPb());
+ }
+
+ MaintenanceWindows toPb() {
+ return new MaintenanceWindows()
+ .setName(name)
+ .setDescription(description)
+ .setBeginTime(beginTime != null ? TIMESTAMP_FORMATTER.print(beginTime) : null)
+ .setEndTime(endTime != null ? TIMESTAMP_FORMATTER.print(endTime) : null);
+ }
+
+ static MaintenanceWindow fromPb(MaintenanceWindows windowPb) {
+ return new MaintenanceWindow(windowPb.getName(), windowPb.getDescription(),
+ windowPb.getBeginTime() != null
+ ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getBeginTime()) : null,
+ windowPb.getEndTime() != null
+ ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getEndTime()) : null);
+ }
+ }
+
+ static final class Builder {
+
+ private ZoneId zoneId;
+ private String id;
+ private Long creationTimestamp;
+ private String description;
+
+ private Status status;
+ private List maintenanceWindows;
+ private RegionId region;
+ private DeprecationStatus deprecationStatus;
+
+ private Builder() {}
+
+ Builder zoneId(ZoneId zoneId) {
+ this.zoneId = zoneId;
+ return this;
+ }
+
+ Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ Builder creationTimestamp(Long creationTimestamp) {
+ this.creationTimestamp = creationTimestamp;
+ return this;
+ }
+
+ Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ Builder status(Status status) {
+ this.status = status;
+ return this;
+ }
+
+ Builder maintenanceWindows(List maintenanceWindows) {
+ this.maintenanceWindows = maintenanceWindows;
+ return this;
+ }
+
+ Builder region(RegionId region) {
+ this.region = region;
+ return this;
+ }
+
+ Builder deprecationStatus(DeprecationStatus deprecationStatus) {
+ this.deprecationStatus = deprecationStatus;
+ return this;
+ }
+
+ Zone build() {
+ return new Zone(this);
+ }
+ }
+
+ private Zone(Builder builder) {
+ this.zoneId = builder.zoneId;
+ this.id = builder.id;
+ this.creationTimestamp = builder.creationTimestamp;
+ this.description = builder.description;
+ this.status = builder.status;
+ this.maintenanceWindows = builder.maintenanceWindows;
+ this.region = builder.region;
+ this.deprecationStatus = builder.deprecationStatus;
+ }
+
+ /**
+ * Returns the zone's identity.
+ */
+ public ZoneId zoneId() {
+ return zoneId;
+ }
+
+ /**
+ * Returns the creation timestamp in milliseconds since epoch.
+ */
+ public Long creationTimestamp() {
+ return creationTimestamp;
+ }
+
+ /**
+ * Returns an optional textual description of the zone.
+ */
+ public String description() {
+ return description;
+ }
+
+ /**
+ * Returns an unique identifier for the zone; defined by the service.
+ */
+ public String id() {
+ return id;
+ }
+
+ /**
+ * Returns the status of the zone.
+ */
+ public Status status() {
+ return status;
+ }
+
+ /**
+ * Returns the scheduled maintenance windows for this zone, if any. When the zone is in a
+ * maintenance window, all resources which reside in the zone will be unavailable.
+ *
+ * @see Maintenance
+ * Windows
+ */
+ public List maintenanceWindows() {
+ return maintenanceWindows;
+ }
+
+ /**
+ * Returns the identity of the region that hosts the zone.
+ */
+ public RegionId region() {
+ return region;
+ }
+
+ /**
+ * Returns the deprecation status of the zone. If {@link DeprecationStatus#status()} is either
+ * {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} the zone
+ * should not be used. Returns {@code null} if the zone is not deprecated.
+ */
+ public DeprecationStatus deprecationStatus() {
+ return deprecationStatus;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("zoneId", zoneId)
+ .add("id", id)
+ .add("creationTimestamp", creationTimestamp)
+ .add("description", description)
+ .add("status", status)
+ .add("maintenanceWindows", maintenanceWindows)
+ .add("region", region)
+ .add("deprecationStatus", deprecationStatus)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(zoneId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb());
+ }
+
+ com.google.api.services.compute.model.Zone toPb() {
+ com.google.api.services.compute.model.Zone zonePb =
+ new com.google.api.services.compute.model.Zone();
+ if (id != null) {
+ zonePb.setId(new BigInteger(id));
+ }
+ if (creationTimestamp != null) {
+ zonePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp));
+ }
+ zonePb.setName(zoneId.zone());
+ zonePb.setDescription(description);
+ zonePb.setSelfLink(zoneId.selfLink());
+ if (status != null) {
+ zonePb.setStatus(status.name());
+ }
+ if (maintenanceWindows != null) {
+ zonePb.setMaintenanceWindows(
+ Lists.transform(maintenanceWindows, MaintenanceWindow.TO_PB_FUNCTION));
+ }
+ if (region != null) {
+ zonePb.setRegion(region.selfLink());
+ }
+ if (deprecationStatus != null) {
+ zonePb.setDeprecated(deprecationStatus.toPb());
+ }
+ return zonePb;
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+
+ static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) {
+ Builder builder = builder();
+ builder.zoneId(ZoneId.fromUrl(zonePb.getSelfLink()));
+ if (zonePb.getId() != null) {
+ builder.id(zonePb.getId().toString());
+ }
+ if (zonePb.getCreationTimestamp() != null) {
+ builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(zonePb.getCreationTimestamp()));
+ }
+ builder.description(zonePb.getDescription());
+ if (zonePb.getStatus() != null) {
+ builder.status(Status.valueOf(zonePb.getStatus()));
+ }
+ if (zonePb.getMaintenanceWindows() != null) {
+ builder.maintenanceWindows(
+ Lists.transform(zonePb.getMaintenanceWindows(), MaintenanceWindow.FROM_PB_FUNCTION));
+ }
+ if (zonePb.getRegion() != null) {
+ builder.region(RegionId.fromUrl(zonePb.getRegion()));
+ }
+ if (zonePb.getDeprecated() != null) {
+ builder.deprecationStatus(
+ DeprecationStatus.fromPb(zonePb.getDeprecated(), ZoneId.FROM_URL_FUNCTION));
+ }
+ return builder.build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java
new file mode 100644
index 000000000000..74ac5be58201
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java
@@ -0,0 +1,123 @@
+/*
+ * 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.common.base.Function;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A Google Compute Engine zone identity.
+ */
+public final class ZoneId extends ResourceId {
+
+ static final Function FROM_URL_FUNCTION = new Function() {
+ @Override
+ public ZoneId apply(String pb) {
+ return ZoneId.fromUrl(pb);
+ }
+ };
+ static final Function TO_URL_FUNCTION = new Function() {
+ @Override
+ public String apply(ZoneId zoneId) {
+ return zoneId.selfLink();
+ }
+ };
+
+ private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)";
+ private static final Pattern PATTERN = Pattern.compile(REGEX);
+ private static final long serialVersionUID = -7635391994812946733L;
+
+ private final String zone;
+
+ private ZoneId(String project, String zone) {
+ super(project);
+ this.zone = checkNotNull(zone);
+ }
+
+ /**
+ * Returns the name of the zone.
+ */
+ public final String zone() {
+ return zone;
+ }
+
+ @Override
+ public String selfLink() {
+ return super.selfLink() + "/zones/" + zone;
+ }
+
+ @Override
+ ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("zone", zone);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(baseHashCode(), zone);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ZoneId
+ && baseEquals((ZoneId) obj)
+ && Objects.equals(zone, ((ZoneId) obj).zone);
+ }
+
+ @Override
+ ZoneId setProjectId(String projectId) {
+ if (project() != null) {
+ return this;
+ }
+ return ZoneId.of(projectId, zone);
+ }
+
+ /**
+ * Returns a new zone identity given project and zone names.
+ */
+ public static ZoneId of(String project, String zone) {
+ return new ZoneId(project, zone);
+ }
+
+ /**
+ * Returns a new zone identity given zone name.
+ */
+ public static ZoneId of(String zone) {
+ return ZoneId.of(null, zone);
+ }
+
+ /**
+ * Returns {@code true} if the provided string matches the expected format of a zone URL.
+ * Returns {@code false} otherwise.
+ */
+ static boolean matchesUrl(String url) {
+ return url.matches(REGEX);
+ }
+
+ static ZoneId fromUrl(String url) {
+ Matcher matcher = PATTERN.matcher(url);
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException(url + " is not a valid zone URL");
+ }
+ return ZoneId.of(matcher.group(1), matcher.group(2));
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java
new file mode 100644
index 000000000000..60117684c056
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java
@@ -0,0 +1,80 @@
+/*
+ * 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.common.base.MoreObjects.ToStringHelper;
+
+import java.util.Objects;
+
+/**
+ * A base class for the identity of Google Compute Engine resources that live in a zone.
+ */
+public abstract class ZoneResourceId extends ResourceId {
+
+ static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/";
+ private static final long serialVersionUID = -6249546895344926888L;
+
+ private final String zone;
+
+ ZoneResourceId(String project, String zone) {
+ super(project);
+ this.zone = checkNotNull(zone);
+ }
+
+ ZoneResourceId(ZoneId zoneId) {
+ super(zoneId.project());
+ this.zone = checkNotNull(zoneId.zone());
+ }
+
+ /**
+ * Returns the name of the zone this resource belongs to.
+ */
+ public final String zone() {
+ return zone;
+ }
+
+ /**
+ * Returns the identity of the zone this resource belongs to.
+ */
+ public final ZoneId zoneId() {
+ return ZoneId.of(project(), zone);
+ }
+
+ @Override
+ public String selfLink() {
+ return super.selfLink() + "/zones/" + zone;
+ }
+
+ @Override
+ ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("zone", zone);
+ }
+
+ @Override
+ final int baseHashCode() {
+ return Objects.hash(super.baseHashCode(), zone);
+ }
+
+ @Override
+ final boolean baseEquals(ResourceId resourceId) {
+ return resourceId instanceof ZoneResourceId
+ && super.baseEquals(resourceId)
+ && Objects.equals(zone, ((ZoneResourceId) resourceId).zone);
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
new file mode 100644
index 000000000000..b7a59a9413c4
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
@@ -0,0 +1,20 @@
+/*
+ * 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.spi;
+
+public interface ComputeRpc {
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java
new file mode 100644
index 000000000000..5defc86199ef
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java
@@ -0,0 +1,26 @@
+/*
+ * 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.spi;
+
+import com.google.gcloud.compute.ComputeOptions;
+
+/**
+ * An interface for Compute RPC factory.
+ * Implementation will be loaded via {@link java.util.ServiceLoader}.
+ */
+public interface ComputeRpcFactory extends ServiceRpcFactory {
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java
new file mode 100644
index 000000000000..6667588dd0ef
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java
@@ -0,0 +1,46 @@
+/*
+ * 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.spi;
+
+import com.google.api.client.http.HttpRequestInitializer;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.json.jackson.JacksonFactory;
+import com.google.api.services.compute.Compute;
+import com.google.gcloud.compute.ComputeException;
+import com.google.gcloud.compute.ComputeOptions;
+
+import java.io.IOException;
+
+public class DefaultComputeRpc implements ComputeRpc {
+
+ private final ComputeOptions options;
+ private final Compute compute;
+
+ public DefaultComputeRpc(ComputeOptions options) {
+ HttpTransport transport = options.httpTransportFactory().create();
+ HttpRequestInitializer initializer = options.httpRequestInitializer();
+ this.options = options;
+ compute = new Compute.Builder(transport, new JacksonFactory(), initializer)
+ .setRootUrl(options.host())
+ .setApplicationName(options.applicationName())
+ .build();
+ }
+
+ private static ComputeException translate(IOException exception) {
+ return new ComputeException(exception);
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java
new file mode 100644
index 000000000000..e8d29669da7b
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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 com.google.gcloud.compute.DeprecationStatus.Status;
+
+import org.junit.Test;
+
+public class DeprecationStatusTest {
+
+ private static final Long DELETED = 1453293540000L;
+ private static final Long DEPRECATED = 1453293420000L;
+ private static final Long OBSOLETE = 1453293480000L;
+ private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType");
+ private static final MachineTypeId MACHINE_TYPE_ID =
+ MachineTypeId.of("project", "zone", "machineType");
+ private static final Status STATUS = Status.DELETED;
+ private static final DeprecationStatus DISK_TYPE_STATUS =
+ new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS);
+ private static final DeprecationStatus MACHINE_TYPE_STATUS =
+ new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS);
+
+ @Test
+ public void testConstructor() {
+ assertEquals(DELETED, DISK_TYPE_STATUS.deleted());
+ assertEquals(DEPRECATED, DISK_TYPE_STATUS.deprecated());
+ assertEquals(OBSOLETE, DISK_TYPE_STATUS.obsolete());
+ assertEquals(DISK_TYPE_ID, DISK_TYPE_STATUS.replacement());
+ assertEquals(STATUS, DISK_TYPE_STATUS.status());
+ assertEquals(DELETED, MACHINE_TYPE_STATUS.deleted());
+ assertEquals(DEPRECATED, MACHINE_TYPE_STATUS.deprecated());
+ assertEquals(OBSOLETE, MACHINE_TYPE_STATUS.obsolete());
+ assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE_STATUS.replacement());
+ assertEquals(STATUS, MACHINE_TYPE_STATUS.status());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ DeprecationStatus diskStatus =
+ DeprecationStatus.fromPb(DISK_TYPE_STATUS.toPb(), DiskTypeId.FROM_URL_FUNCTION);
+ compareDeprecationStatus(DISK_TYPE_STATUS, diskStatus);
+ DeprecationStatus machineStatus =
+ DeprecationStatus.fromPb(MACHINE_TYPE_STATUS.toPb(), MachineTypeId.FROM_URL_FUNCTION);
+ compareDeprecationStatus(MACHINE_TYPE_STATUS, machineStatus);
+ diskStatus = new DeprecationStatus<>(null, DEPRECATED, null, DISK_TYPE_ID, STATUS);
+ assertEquals(diskStatus,
+ DeprecationStatus.fromPb(diskStatus.toPb(), DiskTypeId.FROM_URL_FUNCTION));
+ machineStatus = new DeprecationStatus<>(null, DEPRECATED, null, MACHINE_TYPE_ID, STATUS);
+ assertEquals(machineStatus,
+ DeprecationStatus.fromPb(machineStatus.toPb(), MachineTypeId.FROM_URL_FUNCTION));
+ }
+
+ private void compareDeprecationStatus(DeprecationStatus expected, DeprecationStatus value) {
+ assertEquals(expected, value);
+ assertEquals(expected.deleted(), value.deleted());
+ assertEquals(expected.deprecated(), value.deprecated());
+ assertEquals(expected.obsolete(), value.obsolete());
+ assertEquals(expected.replacement(), value.replacement());
+ assertEquals(expected.status(), value.status());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java
new file mode 100644
index 000000000000..5ff61d5777ba
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class DiskTypeIdTest {
+
+ private static final String PROJECT = "project";
+ private static final String ZONE = "zone";
+ private static final String DISK_TYPE = "diskType";
+ private static final String URL =
+ "https://www.googleapis.com/compute/v1/projects/project/zones/zone/diskTypes/diskType";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testOf() {
+ DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE);
+ assertEquals(PROJECT, diskTypeId.project());
+ assertEquals(ZONE, diskTypeId.zone());
+ assertEquals(DISK_TYPE, diskTypeId.diskType());
+ assertEquals(URL, diskTypeId.selfLink());
+ diskTypeId = DiskTypeId.of(ZONE, DISK_TYPE);
+ assertNull(diskTypeId.project());
+ assertEquals(ZONE, diskTypeId.zone());
+ assertEquals(DISK_TYPE, diskTypeId.diskType());
+ }
+
+ @Test
+ public void testToAndFromUrl() {
+ DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE);
+ assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT));
+ compareDiskTypeId(diskTypeId, DiskTypeId.fromUrl(diskTypeId.selfLink()));
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("notMatchingUrl is not a valid disk type URL");
+ DiskTypeId.fromUrl("notMatchingUrl");
+ }
+
+ @Test
+ public void testSetProjectId() {
+ DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE);
+ assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT));
+ compareDiskTypeId(diskTypeId, DiskTypeId.of(ZONE, DISK_TYPE).setProjectId(PROJECT));
+ }
+
+ @Test
+ public void testMatchesUrl() {
+ assertTrue(DiskTypeId.matchesUrl(DiskTypeId.of(PROJECT, ZONE, DISK_TYPE).selfLink()));
+ assertFalse(DiskTypeId.matchesUrl("notMatchingUrl"));
+ }
+
+ private void compareDiskTypeId(DiskTypeId expected, DiskTypeId value) {
+ assertEquals(expected, value);
+ assertEquals(expected.project(), expected.project());
+ assertEquals(expected.zone(), expected.zone());
+ assertEquals(expected.diskType(), expected.diskType());
+ assertEquals(expected.selfLink(), expected.selfLink());
+ assertEquals(expected.hashCode(), expected.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java
new file mode 100644
index 000000000000..7cacf256523a
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.junit.Test;
+
+import java.math.BigInteger;
+
+public class DiskTypeTest {
+
+ private static final String ID = "42";
+ private static final Long CREATION_TIMESTAMP = 1453293540000L;
+ private static final String DESCRIPTION = "description";
+ private static final String VALID_DISK_SIZE = "10GB-10TB";
+ private static final Long DEFAULT_DISK_SIZE_GB = 10L;
+ private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType");
+ private static final Long DELETED = 1453293540000L;
+ private static final Long DEPRECATED = 1453293420000L;
+ private static final Long OBSOLETE = 1453293480000L;
+ private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED;
+ private static final DeprecationStatus DEPRECATION_STATUS =
+ new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS);
+ private static final DiskType DISK_TYPE = DiskType.builder()
+ .id(ID)
+ .diskTypeId(DISK_TYPE_ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .validDiskSize(VALID_DISK_SIZE)
+ .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB)
+ .deprecationStatus(DEPRECATION_STATUS)
+ .build();
+
+ @Test
+ public void testBuilder() {
+ assertEquals(ID, DISK_TYPE.id());
+ assertEquals(DISK_TYPE_ID, DISK_TYPE.diskTypeId());
+ assertEquals(CREATION_TIMESTAMP, DISK_TYPE.creationTimestamp());
+ assertEquals(DESCRIPTION, DISK_TYPE.description());
+ assertEquals(VALID_DISK_SIZE, DISK_TYPE.validDiskSize());
+ assertEquals(DEFAULT_DISK_SIZE_GB, DISK_TYPE.defaultDiskSizeGb());
+ assertEquals(DEPRECATION_STATUS, DISK_TYPE.deprecationStatus());
+ }
+
+ @Test
+ public void testToPbAndFromPb() {
+ compareDiskTypes(DISK_TYPE, DiskType.fromPb(DISK_TYPE.toPb()));
+ DiskType diskType = DiskType.builder().diskTypeId(DISK_TYPE_ID).build();
+ compareDiskTypes(diskType, DiskType.fromPb(diskType.toPb()));
+ }
+
+ private void compareDiskTypes(DiskType expected, DiskType value) {
+ assertEquals(expected, value);
+ assertEquals(expected.id(), value.id());
+ assertEquals(expected.diskTypeId(), value.diskTypeId());
+ assertEquals(expected.creationTimestamp(), value.creationTimestamp());
+ assertEquals(expected.description(), value.description());
+ assertEquals(expected.validDiskSize(), value.validDiskSize());
+ assertEquals(expected.defaultDiskSizeGb(), value.defaultDiskSizeGb());
+ assertEquals(expected.deprecationStatus(), value.deprecationStatus());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java
new file mode 100644
index 000000000000..d06fd48cff9a
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class LicenseIdTest {
+
+ private static final String PROJECT = "project";
+ private static final String LICENSE = "license";
+ private static final String URL =
+ "https://www.googleapis.com/compute/v1/projects/project/global/licenses/license";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testOf() {
+ LicenseId licenseId = LicenseId.of(PROJECT, LICENSE);
+ assertEquals(PROJECT, licenseId.project());
+ assertEquals(LICENSE, licenseId.license());
+ assertEquals(URL, licenseId.selfLink());
+ licenseId = LicenseId.of(LICENSE);
+ assertNull(licenseId.project());
+ assertEquals(LICENSE, licenseId.license());
+ }
+
+ @Test
+ public void testToAndFromUrl() {
+ LicenseId licenseId = LicenseId.of(PROJECT, LICENSE);
+ compareLicenseId(licenseId, LicenseId.fromUrl(licenseId.selfLink()));
+ }
+
+ @Test
+ public void testSetProjectId() {
+ LicenseId licenseId = LicenseId.of(PROJECT, LICENSE);
+ assertSame(licenseId, licenseId.setProjectId(PROJECT));
+ compareLicenseId(licenseId, LicenseId.of(LICENSE).setProjectId(PROJECT));
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("notMatchingUrl is not a valid license URL");
+ LicenseId.fromUrl("notMatchingUrl");
+ }
+
+ @Test
+ public void testMatchesUrl() {
+ assertTrue(LicenseId.matchesUrl(LicenseId.of(PROJECT, LICENSE).selfLink()));
+ assertFalse(LicenseId.matchesUrl("notMatchingUrl"));
+ }
+
+ private void compareLicenseId(LicenseId expected, LicenseId value) {
+ assertEquals(expected, value);
+ assertEquals(expected.project(), expected.project());
+ assertEquals(expected.license(), expected.license());
+ assertEquals(expected.selfLink(), expected.selfLink());
+ assertEquals(expected.hashCode(), expected.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java
new file mode 100644
index 000000000000..c9fb95fab9c6
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.junit.Test;
+
+public class LicenseTest {
+
+ private static final LicenseId LICENSE_ID = LicenseId.of("project", "license");
+ private static final Boolean CHARGES_USE_FEE = true;
+ private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE);
+
+ @Test
+ public void testBuilder() {
+ assertEquals(LICENSE_ID, LICENSE.licenseId());
+ assertEquals(CHARGES_USE_FEE, LICENSE.chargesUseFee());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ License license = License.fromPb(LICENSE.toPb());
+ compareLicenses(LICENSE, license);
+ assertEquals(LICENSE_ID.project(), license.licenseId().project());
+ assertEquals(LICENSE_ID.license(), license.licenseId().license());
+ }
+
+ private void compareLicenses(License expected, License value) {
+ assertEquals(expected, value);
+ assertEquals(expected.licenseId(), value.licenseId());
+ assertEquals(expected.chargesUseFee(), value.chargesUseFee());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java
new file mode 100644
index 000000000000..7e3f4d7eae35
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class MachineTypeIdTest {
+
+ private static final String PROJECT = "project";
+ private static final String ZONE = "zone";
+ private static final String TYPE = "type";
+ private static final String URL =
+ "https://www.googleapis.com/compute/v1/projects/project/zones/zone/machineTypes/type";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testOf() {
+ MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE);
+ assertEquals(PROJECT, machineTypeId.project());
+ assertEquals(ZONE, machineTypeId.zone());
+ assertEquals(TYPE, machineTypeId.machineType());
+ assertEquals(URL, machineTypeId.selfLink());
+ machineTypeId = MachineTypeId.of(ZONE, TYPE);
+ assertNull(machineTypeId.project());
+ assertEquals(ZONE, machineTypeId.zone());
+ assertEquals(TYPE, machineTypeId.machineType());
+ }
+
+ @Test
+ public void testToAndFromUrl() {
+ MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE);
+ compareMachineTypeId(machineTypeId, MachineTypeId.fromUrl(machineTypeId.selfLink()));
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("notMatchingUrl is not a valid machine type URL");
+ MachineTypeId.fromUrl("notMatchingUrl");
+ }
+
+ @Test
+ public void testSetProjectId() {
+ MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE);
+ assertSame(machineTypeId, machineTypeId.setProjectId(PROJECT));
+ compareMachineTypeId(machineTypeId, MachineTypeId.of(ZONE, TYPE).setProjectId(PROJECT));
+ }
+
+ @Test
+ public void testMatchesUrl() {
+ assertTrue(MachineTypeId.matchesUrl(MachineTypeId.of(PROJECT, ZONE, TYPE).selfLink()));
+ assertFalse(MachineTypeId.matchesUrl("notMatchingUrl"));
+ }
+
+ private void compareMachineTypeId(MachineTypeId expected, MachineTypeId value) {
+ assertEquals(expected, value);
+ assertEquals(expected.project(), expected.project());
+ assertEquals(expected.zone(), expected.zone());
+ assertEquals(expected.machineType(), expected.machineType());
+ assertEquals(expected.selfLink(), expected.selfLink());
+ assertEquals(expected.hashCode(), expected.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java
new file mode 100644
index 000000000000..969b370ddce8
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+
+import java.util.List;
+
+public class MachineTypeTest {
+
+ private static final String ID = "42";
+ private static final Long CREATION_TIMESTAMP = 1453293540000L;
+ private static final String DESCRIPTION = "description";
+ private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type");
+ private static final Integer CPUS = 1;
+ private static final Integer MEMORY_MB = 2;
+ private static final List SCRATCH_DISKS = ImmutableList.of(3);
+ private static final Integer MAXIMUM_PERSISTENT_DISKS = 4;
+ private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L;
+ private static final Long DELETED = 1453293540000L;
+ private static final Long DEPRECATED = 1453293420000L;
+ private static final Long OBSOLETE = 1453293480000L;
+ private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED;
+ private static final DeprecationStatus DEPRECATION_STATUS =
+ new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS);
+ private static final MachineType MACHINE_TYPE = MachineType.builder()
+ .id(ID)
+ .machineTypeId(MACHINE_TYPE_ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .cpus(CPUS)
+ .memoryMb(MEMORY_MB)
+ .scratchDisksSizeGb(SCRATCH_DISKS)
+ .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS)
+ .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB)
+ .deprecationStatus(DEPRECATION_STATUS)
+ .build();
+
+ @Test
+ public void testBuilder() {
+ assertEquals(ID, MACHINE_TYPE.id());
+ assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE.machineTypeId());
+ assertEquals(CREATION_TIMESTAMP, MACHINE_TYPE.creationTimestamp());
+ assertEquals(DESCRIPTION, MACHINE_TYPE.description());
+ assertEquals(CPUS, MACHINE_TYPE.cpus());
+ assertEquals(MEMORY_MB, MACHINE_TYPE.memoryMb());
+ assertEquals(SCRATCH_DISKS, MACHINE_TYPE.scratchDisksSizeGb());
+ assertEquals(MAXIMUM_PERSISTENT_DISKS, MACHINE_TYPE.maximumPersistentDisks());
+ assertEquals(MAXIMUM_PERSISTENT_DISKS_SIZE_GB, MACHINE_TYPE.maximumPersistentDisksSizeGb());
+ assertEquals(DEPRECATION_STATUS, MACHINE_TYPE.deprecationStatus());
+ }
+
+ @Test
+ public void testToPbAndFromPb() {
+ compareMachineTypes(MACHINE_TYPE, MachineType.fromPb(MACHINE_TYPE.toPb()));
+ MachineType machineType = MachineType.builder().machineTypeId(MACHINE_TYPE_ID).build();
+ compareMachineTypes(machineType, MachineType.fromPb(machineType.toPb()));
+ }
+
+ private void compareMachineTypes(MachineType expected, MachineType value) {
+ assertEquals(expected, value);
+ assertEquals(expected.machineTypeId(), value.machineTypeId());
+ assertEquals(expected.id(), value.id());
+ assertEquals(expected.creationTimestamp(), value.creationTimestamp());
+ assertEquals(expected.description(), value.description());
+ assertEquals(expected.cpus(), value.cpus());
+ assertEquals(expected.memoryMb(), value.memoryMb());
+ assertEquals(expected.scratchDisksSizeGb(), value.scratchDisksSizeGb());
+ assertEquals(expected.maximumPersistentDisks(), value.maximumPersistentDisks());
+ assertEquals(expected.maximumPersistentDisksSizeGb(), value.maximumPersistentDisksSizeGb());
+ assertEquals(expected.deprecationStatus(), value.deprecationStatus());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java
new file mode 100644
index 000000000000..3474a73c3030
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class RegionIdTest {
+
+ private static final String PROJECT = "project";
+ private static final String REGION = "region";
+ private static final String URL =
+ "https://www.googleapis.com/compute/v1/projects/project/regions/region";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testOf() {
+ RegionId regionId = RegionId.of(PROJECT, REGION);
+ assertEquals(PROJECT, regionId.project());
+ assertEquals(REGION, regionId.region());
+ assertEquals(URL, regionId.selfLink());
+ regionId = RegionId.of(REGION);
+ assertNull(regionId.project());
+ assertEquals(REGION, regionId.region());
+ }
+
+ @Test
+ public void testToAndFromUrl() {
+ RegionId regionId = RegionId.of(PROJECT, REGION);
+ compareRegionId(regionId, RegionId.fromUrl(regionId.selfLink()));
+ }
+
+ @Test
+ public void testSetProjectId() {
+ RegionId regionId = RegionId.of(PROJECT, REGION);
+ assertSame(regionId, regionId.setProjectId(PROJECT));
+ compareRegionId(regionId, RegionId.of(REGION).setProjectId(PROJECT));
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("notMatchingUrl is not a valid region URL");
+ RegionId.fromUrl("notMatchingUrl");
+ }
+
+ @Test
+ public void testMatchesUrl() {
+ assertTrue(RegionId.matchesUrl(RegionId.of(PROJECT, REGION).selfLink()));
+ assertFalse(RegionId.matchesUrl("notMatchingUrl"));
+ }
+
+ private void compareRegionId(RegionId expected, RegionId value) {
+ assertEquals(expected, value);
+ assertEquals(expected.project(), expected.project());
+ assertEquals(expected.region(), expected.region());
+ assertEquals(expected.selfLink(), expected.selfLink());
+ assertEquals(expected.hashCode(), expected.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java
new file mode 100644
index 000000000000..072823933110
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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 com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+
+import java.math.BigInteger;
+import java.util.List;
+
+public class RegionTest {
+
+ private static final RegionId REGION_ID = RegionId.of("project", "region");
+ private static final String ID = "42";
+ private static final Long CREATION_TIMESTAMP = 1453293540000L;
+ private static final String DESCRIPTION = "description";
+ private static final Region.Status STATUS = Region.Status.DOWN;
+ private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1");
+ private static final ZoneId ZONE_ID2 = ZoneId.of("project", "zone2");
+ private static final List ZONES = ImmutableList.of(ZONE_ID1, ZONE_ID2);
+ private static final Region.Quota QUOTA1 =
+ new Region.Quota("METRIC1", 2, 1);
+ private static final Region.Quota QUOTA2 =
+ new Region.Quota("METRIC2", 4, 3);
+ private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2);
+ private static final Long DELETED = 1453293540000L;
+ private static final Long DEPRECATED = 1453293420000L;
+ private static final Long OBSOLETE = 1453293480000L;
+ private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>(
+ DELETED, DEPRECATED, OBSOLETE, REGION_ID, DeprecationStatus.Status.DELETED);
+ private static final Region REGION = Region.builder()
+ .regionId(REGION_ID)
+ .id(ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .status(STATUS)
+ .zones(ZONES)
+ .quotas(QUOTAS)
+ .deprecationStatus(DEPRECATION_STATUS)
+ .build();
+
+ @Test
+ public void testBuilder() {
+ assertEquals(REGION_ID, REGION.regionId());
+ assertEquals(ID, REGION.id());
+ assertEquals(CREATION_TIMESTAMP, REGION.creationTimestamp());
+ assertEquals(DESCRIPTION, REGION.description());
+ assertEquals(STATUS, REGION.status());
+ assertEquals(ZONES, REGION.zones());
+ assertEquals(QUOTAS, REGION.quotas());
+ assertEquals(DEPRECATION_STATUS, REGION.deprecationStatus());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ Region region = Region.fromPb(REGION.toPb());
+ compareRegions(REGION, region);
+ assertEquals(REGION_ID.project(), region.regionId().project());
+ assertEquals(REGION_ID.region(), region.regionId().region());
+ region = Region.builder().regionId(REGION_ID).build();
+ compareRegions(region, Region.fromPb(region.toPb()));
+ }
+
+ private void compareRegions(Region expected, Region value) {
+ assertEquals(expected, value);
+ assertEquals(expected.regionId(), value.regionId());
+ assertEquals(expected.id(), value.id());
+ assertEquals(expected.creationTimestamp(), value.creationTimestamp());
+ assertEquals(expected.description(), value.description());
+ assertEquals(expected.status(), value.status());
+ assertEquals(expected.zones(), value.zones());
+ assertEquals(expected.quotas(), value.quotas());
+ assertEquals(expected.deprecationStatus(), value.deprecationStatus());
+ 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
new file mode 100644
index 000000000000..74c062fd6c27
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.assertNotSame;
+
+import com.google.common.collect.ImmutableList;
+import com.google.gcloud.AuthCredentials;
+import com.google.gcloud.RetryParams;
+import com.google.gcloud.compute.Zone.MaintenanceWindow;
+
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.List;
+
+public class SerializationTest {
+
+ private static final String ID = "42";
+ private static final Long CREATION_TIMESTAMP = 1453293540000L;
+ private static final String DESCRIPTION = "description";
+ private static final String VALID_DISK_SIZE = "10GB-10TB";
+ private static final Long DEFAULT_DISK_SIZE_GB = 10L;
+ private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType");
+ private static final DiskType DISK_TYPE = DiskType.builder()
+ .id(ID)
+ .diskTypeId(DISK_TYPE_ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .validDiskSize(VALID_DISK_SIZE)
+ .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB)
+ .build();
+ private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type");
+ private static final Integer GUEST_CPUS = 1;
+ private static final Integer MEMORY_MB = 2;
+ private static final List SCRATCH_DISKS = ImmutableList.of(3);
+ private static final Integer MAXIMUM_PERSISTENT_DISKS = 4;
+ private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L;
+ private static final MachineType MACHINE_TYPE = MachineType.builder()
+ .id(ID)
+ .machineTypeId(MACHINE_TYPE_ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .cpus(GUEST_CPUS)
+ .memoryMb(MEMORY_MB)
+ .scratchDisksSizeGb(SCRATCH_DISKS)
+ .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS)
+ .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB)
+ .build();
+ private static final RegionId REGION_ID = RegionId.of("project", "region");
+ private static final Region.Status REGION_STATUS = Region.Status.DOWN;
+ private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1");
+ private static final ZoneId ZONE_ID2 = ZoneId.of("project", "zone2");
+ private static final List ZONES = ImmutableList.of(ZONE_ID1, ZONE_ID2);
+ private static final Region.Quota QUOTA1 =
+ new Region.Quota("METRIC1", 2, 1);
+ private static final Region.Quota QUOTA2 =
+ new Region.Quota("METRIC2", 4, 3);
+ private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2);
+ private static final Region REGION = Region.builder()
+ .regionId(REGION_ID)
+ .id(ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .status(REGION_STATUS)
+ .zones(ZONES)
+ .quotas(QUOTAS)
+ .build();
+ private static final ZoneId ZONE_ID = ZoneId.of("project", "zone");
+ private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN;
+ private static final Long BEGIN_TIME = 1453293420000L;
+ private static final Long END_TIME = 1453293480000L;
+ private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1",
+ BEGIN_TIME, END_TIME);
+ private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2",
+ BEGIN_TIME, END_TIME);
+ private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2);
+ private static final Zone ZONE = Zone.builder()
+ .zoneId(ZONE_ID)
+ .id(ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .status(ZONE_STATUS)
+ .maintenanceWindows(WINDOWS)
+ .region(REGION_ID)
+ .build();
+ private static final Long DELETED = 1453293540000L;
+ private static final Long DEPRECATED = 1453293420000L;
+ private static final Long OBSOLETE = 1453293480000L;
+ private static final DeprecationStatus DEPRECATION_STATUS =
+ new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID,
+ DeprecationStatus.Status.DELETED);
+ private static final LicenseId LICENSE_ID = LicenseId.of("project", "license");
+ private static final Boolean CHARGES_USE_FEE = true;
+ private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE);
+
+ @Test
+ public void testServiceOptions() throws Exception {
+ ComputeOptions options = ComputeOptions.builder()
+ .projectId("p1")
+ .authCredentials(AuthCredentials.createForAppEngine())
+ .build();
+ ComputeOptions serializedCopy = serializeAndDeserialize(options);
+ assertEquals(options, serializedCopy);
+
+ options = options.toBuilder()
+ .projectId("p2")
+ .retryParams(RetryParams.defaultInstance())
+ .authCredentials(null)
+ .build();
+ serializedCopy = serializeAndDeserialize(options);
+ assertEquals(options, serializedCopy);
+ }
+
+ @Test
+ public void testModelAndRequests() throws Exception {
+ Serializable[] objects = {DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID,
+ REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE, DEPRECATION_STATUS};
+ for (Serializable obj : objects) {
+ Object copy = serializeAndDeserialize(obj);
+ assertEquals(obj, obj);
+ assertEquals(obj, copy);
+ assertNotSame(obj, copy);
+ assertEquals(copy, copy);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private T serializeAndDeserialize(T obj)
+ throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ try (ObjectOutputStream output = new ObjectOutputStream(bytes)) {
+ output.writeObject(obj);
+ }
+ try (ObjectInputStream input =
+ new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) {
+ return (T) input.readObject();
+ }
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java
new file mode 100644
index 000000000000..a147f0e21f63
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class ZoneIdTest {
+
+ private static final String PROJECT = "project";
+ private static final String ZONE = "zone";
+ private static final String URL =
+ "https://www.googleapis.com/compute/v1/projects/project/zones/zone";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testOf() {
+ ZoneId zoneId = ZoneId.of(PROJECT, ZONE);
+ assertEquals(PROJECT, zoneId.project());
+ assertEquals(ZONE, zoneId.zone());
+ assertEquals(URL, zoneId.selfLink());
+ zoneId = ZoneId.of(ZONE);
+ assertNull(zoneId.project());
+ assertEquals(ZONE, zoneId.zone());
+ }
+
+ @Test
+ public void testToAndFromUrl() {
+ ZoneId zoneId = ZoneId.of(PROJECT, ZONE);
+ compareZoneId(zoneId, ZoneId.fromUrl(zoneId.selfLink()));
+ }
+
+ @Test
+ public void testSetProjectId() {
+ ZoneId zoneId = ZoneId.of(PROJECT, ZONE);
+ assertSame(zoneId, zoneId.setProjectId(PROJECT));
+ compareZoneId(zoneId, ZoneId.of(ZONE).setProjectId(PROJECT));
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("notMatchingUrl is not a valid zone URL");
+ ZoneId.fromUrl("notMatchingUrl");
+ }
+
+ @Test
+ public void testMatchesUrl() {
+ assertTrue(ZoneId.matchesUrl(ZoneId.of(PROJECT, ZONE).selfLink()));
+ assertFalse(ZoneId.matchesUrl("notMatchingUrl"));
+ }
+
+ private void compareZoneId(ZoneId expected, ZoneId value) {
+ assertEquals(expected, value);
+ assertEquals(expected.project(), expected.project());
+ assertEquals(expected.zone(), expected.zone());
+ assertEquals(expected.selfLink(), expected.selfLink());
+ assertEquals(expected.hashCode(), expected.hashCode());
+ }
+}
diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java
new file mode 100644
index 000000000000..bdc96d3d9069
--- /dev/null
+++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.gcloud.compute.Zone.MaintenanceWindow;
+
+import org.junit.Test;
+
+import java.math.BigInteger;
+import java.util.List;
+
+public class ZoneTest {
+
+ private static final ZoneId ZONE_ID = ZoneId.of("project", "zone");
+ private static final RegionId REGION_ID = RegionId.of("project", "region");
+ private static final String ID = "42";
+ private static final Long CREATION_TIMESTAMP = 1453293540000L;
+ private static final String DESCRIPTION = "description";
+ private static final Zone.Status STATUS = Zone.Status.DOWN;
+ private static final Long BEGIN_TIME = 1453293420000L;
+ private static final Long END_TIME = 1453293480000L;
+ private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1",
+ BEGIN_TIME, END_TIME);
+ private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2",
+ BEGIN_TIME, END_TIME);
+ private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2);
+ private static final Long DELETED = 1453293540000L;
+ private static final Long DEPRECATED = 1453293420000L;
+ private static final Long OBSOLETE = 1453293480000L;
+ private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>(
+ DELETED, DEPRECATED, OBSOLETE, ZONE_ID, DeprecationStatus.Status.DELETED);
+ private static final Zone ZONE = Zone.builder()
+ .zoneId(ZONE_ID)
+ .id(ID)
+ .creationTimestamp(CREATION_TIMESTAMP)
+ .description(DESCRIPTION)
+ .status(STATUS)
+ .maintenanceWindows(WINDOWS)
+ .deprecationStatus(DEPRECATION_STATUS)
+ .region(REGION_ID)
+ .build();
+
+ @Test
+ public void testBuilder() {
+ assertEquals(REGION_ID, ZONE.region());
+ assertEquals(ID, ZONE.id());
+ assertEquals(CREATION_TIMESTAMP, ZONE.creationTimestamp());
+ assertEquals(DESCRIPTION, ZONE.description());
+ assertEquals(STATUS, ZONE.status());
+ assertEquals(WINDOWS, ZONE.maintenanceWindows());
+ assertEquals(REGION_ID, ZONE.region());
+ assertEquals(DEPRECATION_STATUS, ZONE.deprecationStatus());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ com.google.api.services.compute.model.Zone zonePb = ZONE.toPb();
+ assertEquals(REGION_ID.selfLink(), zonePb.getRegion());
+ Zone zone = Zone.fromPb(zonePb);
+ compareZones(ZONE, zone);
+ assertEquals(ZONE_ID.project(), zone.zoneId().project());
+ assertEquals(ZONE_ID.zone(), zone.zoneId().zone());
+ zone = Zone.builder().zoneId(ZONE_ID).build();
+ compareZones(zone, Zone.fromPb(zone.toPb()));
+ }
+
+ private void compareZones(Zone expected, Zone value) {
+ assertEquals(expected, value);
+ assertEquals(expected.zoneId(), value.zoneId());
+ assertEquals(expected.id(), value.id());
+ assertEquals(expected.creationTimestamp(), value.creationTimestamp());
+ assertEquals(expected.description(), value.description());
+ assertEquals(expected.status(), value.status());
+ assertEquals(expected.maintenanceWindows(), value.maintenanceWindows());
+ assertEquals(expected.region(), value.region());
+ assertEquals(expected.deprecationStatus(), value.deprecationStatus());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}
diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml
index adfa716fe27b..e76d349483bd 100644
--- a/gcloud-java/pom.xml
+++ b/gcloud-java/pom.xml
@@ -18,6 +18,11 @@
gcloud-java-bigquery
${project.version}
+
+ ${project.groupId}
+ gcloud-java-compute
+ ${project.version}
+
${project.groupId}
gcloud-java-core
diff --git a/pom.xml b/pom.xml
index 4bc8f37c35de..5f37fd2b7d6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,6 +95,7 @@
gcloud-java
gcloud-java-bigquery
+ gcloud-java-compute
gcloud-java-contrib
gcloud-java-core
gcloud-java-datastore