diff --git a/.travis.yml b/.travis.yml
index c023116917a3..1e4b639b0e0d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,7 +9,7 @@ before_install:
- cp target/travis/settings.xml ~/.m2/settings.xml
install: mvn install -DskipTests=true -Dgpg.skip=true
script:
-- utilities/verify.sh
+- travis_wait 30 utilities/verify.sh
after_success:
- utilities/after_success.sh
env:
diff --git a/README.md b/README.md
index 6bc56bad250a..0768939df6b3 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services.
This client supports the following Google Cloud Platform services:
- [Google Cloud BigQuery] (#google-cloud-bigquery-alpha) (Alpha)
+- [Google Cloud Compute] (#google-cloud-compute-alpha) (Alpha)
- [Google Cloud Datastore] (#google-cloud-datastore)
- [Google Cloud DNS] (#google-cloud-dns-alpha) (Alpha)
- [Google Cloud Resource Manager] (#google-cloud-resource-manager-alpha) (Alpha)
@@ -50,6 +51,8 @@ Example Applications
- [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality
- Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/bigquery/BigQueryExample.html).
+- [`ComputeExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java) - A simple command line interface providing some of Cloud Compute's functionality
+ - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/compute/ComputeExample.html).
- [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf.
- This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service.
- [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java) - A simple command line interface for Cloud Datastore
@@ -173,6 +176,78 @@ if (loadJob.status().error() != null) {
}
```
+Google Cloud Compute (Alpha)
+----------------------
+
+- [API Documentation][compute-api]
+- [Official Documentation][cloud-compute-docs]
+
+#### Preview
+
+Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that
+you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere.
+
+The first snippet shows how to create a snapshot from an existing disk. Complete source code can be
+found at
+[CreateSnapshot.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java).
+
+```java
+import com.google.cloud.compute.Compute;
+import com.google.cloud.compute.ComputeOptions;
+import com.google.cloud.compute.Disk;
+import com.google.cloud.compute.DiskId;
+import com.google.cloud.compute.Operation;
+import com.google.cloud.compute.Snapshot;
+
+Compute compute = ComputeOptions.defaultInstance().service();
+DiskId diskId = DiskId.of("us-central1-a", "disk-name");
+Disk disk = compute.getDisk(diskId, Compute.DiskOption.fields());
+if (disk != null) {
+ String snapshotName = "disk-name-snapshot";
+ Operation operation = disk.createSnapshot(snapshotName);
+ while (!operation.isDone()) {
+ Thread.sleep(1000L);
+ }
+ if (operation.errors() == null) {
+ // use snapshot
+ Snapshot snapshot = compute.getSnapshot("disk-name-snapshot");
+ }
+}
+```
+The second snippet shows how to create a virtual machine instance. Complete source code can be found
+at
+[CreateInstance.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java).
+```java
+import com.google.cloud.compute.AttachedDisk;
+import com.google.cloud.compute.Compute;
+import com.google.cloud.compute.ComputeOptions;
+import com.google.cloud.compute.ImageId;
+import com.google.cloud.compute.Instance;
+import com.google.cloud.compute.InstanceId;
+import com.google.cloud.compute.InstanceInfo;
+import com.google.cloud.compute.MachineTypeId;
+import com.google.cloud.compute.NetworkId;
+import com.google.cloud.compute.NetworkInterface;
+import com.google.cloud.compute.Operation;
+
+Compute compute = ComputeOptions.defaultInstance().service();
+ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329");
+NetworkId networkId = NetworkId.of("default");
+AttachedDisk attachedDisk = AttachedDisk.of(AttachedDisk.CreateDiskConfiguration.of(imageId));
+NetworkInterface networkInterface = NetworkInterface.of(networkId);
+InstanceId instanceId = InstanceId.of("us-central1-a", "instance-name");
+MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1");
+Operation operation =
+ compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface));
+while (!operation.isDone()) {
+ Thread.sleep(1000L);
+}
+if (operation.errors() == null) {
+ // use instance
+ Instance instance = compute.getInstance(instanceId);
+}
+```
+
Google Cloud Datastore
----------------------
@@ -455,3 +530,7 @@ Apache 2.0 - See [LICENSE] for more information.
[cloud-bigquery]: https://cloud.google.com/bigquery/
[cloud-bigquery-docs]: https://cloud.google.com/bigquery/docs/overview
[bigquery-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/bigquery/package-summary.html
+
+[cloud-compute]: https://cloud.google.com/compute/
+[cloud-compute-docs]: https://cloud.google.com/compute/docs/overview
+[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/compute/package-summary.html
diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md
new file mode 100644
index 000000000000..7bd7c83ee523
--- /dev/null
+++ b/gcloud-java-compute/README.md
@@ -0,0 +1,267 @@
+Google Cloud Java Client for Compute (Alpha)
+====================================
+
+Java idiomatic client for [Google Cloud Compute](https://cloud.google.com/compute).
+
+[](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
+[](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
+[]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-compute.svg)
+[](https://www.codacy.com/app/mziccard/gcloud-java)
+[](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
+
+- [Homepage](https://googlecloudplatform.github.io/gcloud-java/)
+- [API Documentation](http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/compute/package-summary.html)
+
+> 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
+```xml
+
+ com.google.cloud
+ gcloud-java-compute
+ 0.2.0
+
+```
+If you are using Gradle, add this to your dependencies
+```Groovy
+compile 'com.google.cloud:gcloud-java-compute:0.2.0'
+```
+If you are using SBT, add this to your dependencies
+```Scala
+libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.0"
+```
+
+Example Application
+-------------------
+
+[`ComputeExample`](../gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java)
+is a simple command line interface that provides some of Google Cloud Compute Engine's
+functionality. Read more about using the application on the
+[`ComputeExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/compute/ComputeExample.html).
+
+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
+---------------
+
+#### Prerequisites
+For this tutorial, you will need a [Google Developers Console](https://console.developers.google.com/)
+project with the Compute Engine API enabled. You will need to [enable billing](https://support.google.com/cloud/answer/6158867?hl=en)
+to use Google Cloud DNS. [Follow these instructions](https://cloud.google.com/docs/authentication#preparation)
+to get your project set up. You will also need to set up the local development environment by
+[installing the Google Cloud SDK](https://cloud.google.com/sdk/) and running the following commands
+in command line: `gcloud auth login` and `gcloud config set project [YOUR PROJECT ID]`.
+
+#### Installation and setup
+You'll need to obtain the `gcloud-java-compute` library. See the [Quickstart](#quickstart) section
+to add `gcloud-java-compute` as a dependency in your code.
+
+#### Creating an authorized service object
+To make authenticated requests to Google Cloud Compute Engine, you must create a service object with
+credentials. You can then make API calls by calling methods on the Compute service object. The
+simplest way to authenticate is to use [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials).
+These credentials are automatically inferred from your environment, so you only need the following
+code to create your service object:
+
+```java
+import com.google.cloud.compute.Compute;
+import com.google.cloud.compute.ComputeOptions;
+
+Compute compute = ComputeOptions.defaultInstance().service();
+```
+
+For other authentication options, see the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication)
+page.
+
+#### Creating a region IP address
+An external region IP address can be associated to a Google Compute Engine instance to communicate
+with instances in different regions or to communicate with the instance from ouside of Compute
+Engine. In this code snippet, we will create a new external region address.
+
+Add the following imports at the top of your file:
+
+```java
+import com.google.cloud.compute.AddressInfo;
+import com.google.cloud.compute.Operation;
+import com.google.cloud.compute.RegionAddressId;
+```
+
+Then add the following code to create an address. Most Compute Engine calls return an `Operation`
+object that can be used to wait for operation completion and to check whether operation failed or
+succeeded:
+
+```java
+RegionAddressId addressId = RegionAddressId.of("us-central1", "test-address");
+Operation operation = compute.create(AddressInfo.of(addressId));
+while (!operation.isDone()) {
+ Thread.sleep(1000L);
+}
+operation = operation.reload();
+if (operation.errors() == null) {
+ System.out.println("Address " + addressId + " was successfully created");
+} else {
+ // inspect operation.errors()
+ throw new RuntimeException("Address creation failed");
+}
+```
+
+#### Creating a persistent disk
+A persistent disk can be used as primary storage for your virtual machine instances. Persistent
+disks can be created empty, from a disk image or from a disk snapshot. Compute Engine offers
+[publicly-available images](https://cloud.google.com/compute/docs/operating-systems/) of certain
+operating systems that you can use. In this code snippet, we will create a new persistent disk from
+a publicly-available image.
+
+Add the following imports at the top of your file:
+
+```java
+import com.google.cloud.compute.DiskInfo;
+import com.google.cloud.compute.DiskId;
+import com.google.cloud.compute.ImageDiskConfiguration;
+import com.google.cloud.compute.ImageId;
+```
+
+Then add the following code to create a disk and wait for disk creation to terminate.
+
+```java
+ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329");
+DiskId diskId = DiskId.of("us-central1-a", "test-disk");
+ImageDiskConfiguration diskConfiguration = ImageDiskConfiguration.of(imageId);
+DiskInfo disk = DiskInfo.of(diskId, diskConfiguration);
+Operation operation = compute.create(disk);
+while (!operation.isDone()) {
+ Thread.sleep(1000L);
+}
+operation = operation.reload();
+if (operation.errors() == null) {
+ System.out.println("Disk " + diskId + " was successfully created");
+} else {
+ // inspect operation.errors()
+ throw new RuntimeException("Disk creation failed");
+}
+```
+
+#### Creating a virtual machine instance
+An Google Compute Engine instance is a virtual machine (VM) hosted on Google's infrastructure. An
+instance can be created given it's identity, a machine type, one boot disk and a network interface.
+In this code snippet, we will create a virtual machine instance in the default network using as a
+boot disk the disk we have just created and assigning to it the just created IP address.
+
+Add the following imports at the top of your file:
+
+```java
+import com.google.cloud.compute.AttachedDisk;
+import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration;
+import com.google.cloud.compute.InstanceId;
+import com.google.cloud.compute.InstanceInfo;
+import com.google.cloud.compute.MachineTypeId;
+import com.google.cloud.compute.NetworkConfiguration;
+import com.google.cloud.compute.NetworkConfiguration.AccessConfig;
+import com.google.cloud.compute.NetworkId;
+import com.google.cloud.compute.NetworkInterface;
+```
+
+Then add the following code to create an instance and wait for instance creation to terminate.
+
+```java
+Address externalIp = compute.getAddress(addressId);
+InstanceId instanceId = InstanceId.of("us-central1-a", "test-instance");
+NetworkId networkId = NetworkId.of("default");
+PersistentDiskConfiguration attachConfiguration =
+ PersistentDiskConfiguration.builder(diskId).boot(true).build();
+AttachedDisk attachedDisk = AttachedDisk.of("dev0", attachConfiguration);
+NetworkInterface networkInterface = NetworkInterface.builder(networkId)
+ .accessConfigurations(AccessConfig.of(externalIp.address()))
+ .build();
+MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1");
+InstanceInfo instance =
+ InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface);
+Operation operation = compute.create(instance);
+while (!operation.isDone()) {
+ Thread.sleep(1000L);
+}
+operation = operation.reload();
+if (operation.errors() == null) {
+ System.out.println("Instance " + instanceId + " was successfully created");
+} else {
+ // inspect operation.errors()
+ throw new RuntimeException("Instance creation failed");
+}
+```
+
+#### Complete source code
+
+In
+[CreateAddressDiskAndInstance.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java)
+we put together all the code shown above into one program. The program assumes that you are
+running on Compute Engine or from your own desktop. To run the example on App Engine, simply move
+the code from the main method to your application's servlet class and change the print statements to
+display on your webpage.
+
+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/cloud/compute/package-summary.html
diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml
new file mode 100644
index 000000000000..40a09b008076
--- /dev/null
+++ b/gcloud-java-compute/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+ gcloud-java-compute
+ jar
+ GCloud Java compute
+ https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-compute
+
+ Java idiomatic client for Google Cloud Compute Engine.
+
+
+ com.google.cloud
+ gcloud-java-pom
+ 0.2.1-SNAPSHOT
+
+
+ gcloud-java-compute
+
+
+
+ ${project.groupId}
+ gcloud-java-core
+ ${project.version}
+
+
+ com.google.apis
+ google-api-services-compute
+ v1-rev103-1.21.0
+ compile
+
+
+ com.google.guava
+ guava-jdk5
+
+
+
+
+ ${project.groupId}
+ gcloud-java-core
+ ${project.version}
+ test-jar
+ test
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.easymock
+ easymock
+ 3.4
+ test
+
+
+
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java
new file mode 100644
index 000000000000..10e99cadb60f
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java
@@ -0,0 +1,191 @@
+/*
+ * 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.cloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.cloud.compute.Compute.AddressOption;
+import com.google.cloud.compute.Compute.OperationOption;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.Objects;
+
+/**
+ * A Google Compute Engine address. With Compute Engine you can create static external IP addresses
+ * that are assigned to your project and persist until you explicitly release them. A region address
+ * can be assigned to a Compute Engine instance or to a regional forwarding rule. Compute Engine
+ * also allows you to create global addresses that are used for global forwarding rules. Both global
+ * addresses and global forwarding rules can only be used for HTTP load balancing. {@code Address}
+ * adds a layer of service-related functionality over {@link AddressInfo}. Objects of this class are
+ * immutable. To get an {@code Address} object with the most recent information use {@link #reload}.
+ *
+ * @see
+ * Static external IP addresses
+ * @see HTTP Load Balancing
+ */
+public class Address extends AddressInfo {
+
+ private static final long serialVersionUID = 3457542817554062712L;
+
+ private final ComputeOptions options;
+ private transient Compute compute;
+
+ /**
+ * A builder for {@code Address} objects.
+ */
+ public static class Builder extends AddressInfo.Builder {
+
+ private final Compute compute;
+ private final AddressInfo.BuilderImpl infoBuilder;
+
+ Builder(Compute compute, AddressId addressId) {
+ this.compute = compute;
+ this.infoBuilder = new AddressInfo.BuilderImpl();
+ this.infoBuilder.addressId(addressId);
+ }
+
+ Builder(Address address) {
+ this.compute = address.compute;
+ this.infoBuilder = new AddressInfo.BuilderImpl(address);
+ }
+
+ @Override
+ public Builder address(String address) {
+ infoBuilder.address(address);
+ return this;
+ }
+
+ @Override
+ Builder creationTimestamp(Long creationTimestamp) {
+ infoBuilder.creationTimestamp(creationTimestamp);
+ return this;
+ }
+
+ @Override
+ public Builder description(String description) {
+ infoBuilder.description(description);
+ return this;
+ }
+
+ @Override
+ Builder generatedId(String generatedId) {
+ infoBuilder.generatedId(generatedId);
+ return this;
+ }
+
+ @Override
+ public Builder addressId(AddressId addressId) {
+ infoBuilder.addressId(addressId);
+ return this;
+ }
+
+ @Override
+ Builder status(Status status) {
+ infoBuilder.status(status);
+ return this;
+ }
+
+ @Override
+ Builder usage(Usage usage) {
+ infoBuilder.usage(usage);
+ return this;
+ }
+
+ @Override
+ public Address build() {
+ return new Address(compute, infoBuilder);
+ }
+ }
+
+ Address(Compute compute, AddressInfo.BuilderImpl infoBuilder) {
+ super(infoBuilder);
+ this.compute = checkNotNull(compute);
+ this.options = compute.options();
+ }
+
+ /**
+ * Checks if this address exists.
+ *
+ * @return {@code true} if this address exists, {@code false} otherwise
+ * @throws ComputeException upon failure
+ */
+ public boolean exists() {
+ return reload(AddressOption.fields()) != null;
+ }
+
+ /**
+ * Fetches the current address' latest information. Returns {@code null} if the address does not
+ * exist.
+ *
+ * @param options address options
+ * @return an {@code Address} object with latest information or {@code null} if not found
+ * @throws ComputeException upon failure
+ */
+ public Address reload(AddressOption... options) {
+ return compute.getAddress(addressId(), options);
+ }
+
+ /**
+ * Deletes this address.
+ *
+ * @return an {@code Operation} object if delete request was successfully sent, {@code null} if
+ * the address was not found
+ * @throws ComputeException upon failure
+ */
+ public Operation delete(OperationOption... options) {
+ return compute.deleteAddress(addressId(), options);
+ }
+
+ /**
+ * Returns the address's {@code Compute} object used to issue requests.
+ */
+ public Compute compute() {
+ return compute;
+ }
+
+ @Override
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null || !obj.getClass().equals(Address.class)) {
+ return false;
+ }
+ Address other = (Address) obj;
+ return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options);
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(super.hashCode(), options);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ this.compute = options.service();
+ }
+
+ static Address fromPb(Compute compute, com.google.api.services.compute.model.Address addressPb) {
+ return new Address(compute, new AddressInfo.BuilderImpl(addressPb));
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressId.java
new file mode 100644
index 000000000000..e5440e6f6d34
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressId.java
@@ -0,0 +1,91 @@
+/*
+ * 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.cloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Base class for Google Compute Engine address identities.
+ */
+public abstract class AddressId extends ResourceId {
+
+ private static final long serialVersionUID = 147328216049936438L;
+
+ private final String address;
+
+ /**
+ * Possible types for a Google Compute Engine address identity.
+ */
+ enum Type {
+ /**
+ * Global static external IP addresses can be assigned to global forwarding rules.
+ */
+ GLOBAL,
+
+ /**
+ * Region static external IP addresses can be assigned to instances and region forwarding rules.
+ */
+ REGION
+ }
+
+ AddressId(String project, String address) {
+ super(project);
+ this.address = checkNotNull(address);
+ }
+
+ /**
+ * Returns the type of this address identity.
+ */
+ public abstract Type type();
+
+ /**
+ * Returns the name of the address resource. The name must be 1-63 characters long and comply with
+ * RFC1035. Specifically, the name must match the regular expression
+ * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter,
+ * and all following characters must be a dash, lowercase letter, or digit, except the last
+ * character, which cannot be a dash.
+ *
+ * @see RFC1035
+ */
+ public String address() {
+ return address;
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("address", address);
+ }
+
+ @Override
+ final int baseHashCode() {
+ return Objects.hash(super.baseHashCode(), address);
+ }
+
+ @Override
+ final boolean baseEquals(ResourceId resourceId) {
+ return resourceId instanceof AddressId
+ && super.baseEquals(resourceId)
+ && Objects.equals(address, ((AddressId) resourceId).address);
+ }
+
+ @Override
+ abstract AddressId setProjectId(String projectId);
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java
new file mode 100644
index 000000000000..9a95c77119c8
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java
@@ -0,0 +1,574 @@
+/*
+ * 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.cloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.api.services.compute.model.Address;
+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 address. With Compute Engine you can create static external IP addresses
+ * that are assigned to your project and persist until you explicitly release them. A region address
+ * can be assigned to a Compute Engine instance or to a regional forwarding rule. To create a region
+ * address, use a {@link RegionAddressId} identity. Compute Engine also allows you to create global
+ * addresses that are used for global forwarding rules. Both global addresses and global forwarding
+ * rules can only be used for HTTP load balancing. To create a global address, use a
+ * {@link GlobalAddressId} identity.
+ *
+ * @see
+ * Static external IP addresses
+ * @see HTTP Load Balancing
+ */
+public class AddressInfo implements Serializable {
+
+ static final Function
FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public AddressInfo apply(Address pb) {
+ return AddressInfo.fromPb(pb);
+ }
+ };
+ static final Function TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public Address apply(AddressInfo addressInfo) {
+ return addressInfo.toPb();
+ }
+ };
+
+ private static final long serialVersionUID = 7678434703520207500L;
+ private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private final String address;
+ private final Long creationTimestamp;
+ private final String description;
+ private final String generatedId;
+ private final AddressId addressId;
+ private final Status status;
+ private final Usage usage;
+
+ /**
+ * The status of the address.
+ */
+ public enum Status {
+
+ /**
+ * The address is reserved for the project and is available for use.
+ */
+ RESERVED,
+
+ /**
+ * The address is currently being used and thus not available.
+ */
+ IN_USE
+ }
+
+ /**
+ * Base class for a Google Compute Engine address's usage information. Implementations of this
+ * class represent different possible usages of a Compute Engine address. {@link InstanceUsage}
+ * contains information for region addresses assigned to a Google Compute Engine instance.
+ * {@link RegionForwardingUsage} contains information for region addresses assigned to one or more
+ * region forwarding rules. {@link GlobalForwardingUsage} contains information for global
+ * addresses assigned to one or more global forwarding rules.
+ */
+ public abstract static class Usage implements Serializable {
+
+ private static final long serialVersionUID = -5028609518171408695L;
+
+ Usage() {}
+
+ /**
+ * Returns the identities of resources currently using this address.
+ */
+ public abstract List extends ResourceId> users();
+
+ final boolean baseEquals(Usage usage) {
+ return Objects.equals(toPb(), usage.toPb());
+ }
+
+ Address toPb() {
+ return new Address().setUsers(Lists.transform(users(), new Function() {
+ @Override
+ public String apply(ResourceId resourceId) {
+ return resourceId.selfLink();
+ }
+ }));
+ }
+
+ @SuppressWarnings("unchecked")
+ static T fromPb(Address addressPb) {
+ String url = addressPb.getUsers().get(0);
+ if (InstanceId.matchesUrl(url)) {
+ return (T) InstanceUsage.fromPb(addressPb);
+ } else if (RegionForwardingRuleId.matchesUrl(url)) {
+ return (T) RegionForwardingUsage.fromPb(addressPb);
+ } else if (GlobalForwardingRuleId.matchesUrl(url)) {
+ return (T) GlobalForwardingUsage.fromPb(addressPb);
+ } else {
+ throw new IllegalArgumentException("Unexpected resource URL for address user");
+ }
+ }
+ }
+
+ /**
+ * Usage information for a Google Compute Engine region address assigned to a virtual machine
+ * instance.
+ */
+ public static final class InstanceUsage extends Usage {
+
+ private static final long serialVersionUID = -5028609518171408695L;
+
+ private final InstanceId instance;
+
+ InstanceUsage(InstanceId instance) {
+ this.instance = checkNotNull(instance);
+ }
+
+ /**
+ * Returns the identity of the instance using the address.
+ */
+ public InstanceId instance() {
+ return instance;
+ }
+
+ @Override
+ public List users() {
+ return ImmutableList.of(instance);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("instance", instance).toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof InstanceUsage && baseEquals((InstanceUsage) obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(instance);
+ }
+
+ @SuppressWarnings("unchecked")
+ static InstanceUsage fromPb(Address addressPb) {
+ return new InstanceUsage(InstanceId.fromUrl(addressPb.getUsers().get(0)));
+ }
+ }
+
+ /**
+ * Usage information for a Google Compute Engine region address assigned to one or more region
+ * forwarding rules.
+ */
+ public static final class RegionForwardingUsage extends Usage {
+
+ private static final long serialVersionUID = -4255145869626427363L;
+
+ private final List forwardingRules;
+
+ RegionForwardingUsage(List forwardingRules) {
+ this.forwardingRules = ImmutableList.copyOf(forwardingRules);
+ }
+
+ /**
+ * Returns a list of identities of region forwarding rules that are currently using the address.
+ */
+ public List forwardingRules() {
+ return forwardingRules;
+ }
+
+ @Override
+ public List users() {
+ return forwardingRules;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("forwardingRules", forwardingRules).toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof RegionForwardingUsage && baseEquals((RegionForwardingUsage) obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(forwardingRules);
+ }
+
+ @SuppressWarnings("unchecked")
+ static RegionForwardingUsage fromPb(Address addressPb) {
+ return new RegionForwardingUsage(
+ Lists.transform(addressPb.getUsers(), RegionForwardingRuleId.FROM_URL_FUNCTION));
+ }
+ }
+
+ /**
+ * Usage information for a Google Compute Engine global address assigned to one or more global
+ * forwarding rules.
+ */
+ public static final class GlobalForwardingUsage extends Usage {
+
+ private static final long serialVersionUID = -2974154224319117433L;
+
+ private final List forwardingRules;
+
+ GlobalForwardingUsage(List forwardingRules) {
+ this.forwardingRules = ImmutableList.copyOf(forwardingRules);
+ }
+
+ /**
+ * Returns a list of identities of global forwarding rules that are currently using the address.
+ */
+ public List forwardingRules() {
+ return forwardingRules;
+ }
+
+ @Override
+ public List users() {
+ return forwardingRules;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("forwardingRules", forwardingRules).toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof GlobalForwardingUsage && baseEquals((GlobalForwardingUsage) obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(forwardingRules);
+ }
+
+ @SuppressWarnings("unchecked")
+ static GlobalForwardingUsage fromPb(Address addressPb) {
+ return new GlobalForwardingUsage(
+ Lists.transform(addressPb.getUsers(), GlobalForwardingRuleId.FROM_URL_FUNCTION));
+ }
+ }
+
+ /**
+ * A builder for {@code AddressInfo} objects.
+ */
+ public abstract static class Builder {
+
+ /**
+ * Sets the actual IP address.
+ */
+ public abstract Builder address(String address);
+
+ abstract Builder creationTimestamp(Long creationTimestamp);
+
+ /**
+ * Sets an optional textual description of the address.
+ */
+ public abstract Builder description(String description);
+
+ abstract Builder generatedId(String generatedId);
+
+ public abstract Builder addressId(AddressId addressId);
+
+ abstract Builder status(Status status);
+
+ abstract Builder usage(Usage usage);
+
+ /**
+ * Creates an {@code AddressInfo} object.
+ */
+ public abstract AddressInfo build();
+ }
+
+ static final class BuilderImpl extends Builder {
+
+ private String address;
+ private Long creationTimestamp;
+ private String description;
+ private String generatedId;
+ private AddressId addressId;
+ private Status status;
+ private Usage usage;
+
+ BuilderImpl() {}
+
+ BuilderImpl(AddressInfo addressInfo) {
+ this.address = addressInfo.address;
+ this.creationTimestamp = addressInfo.creationTimestamp;
+ this.description = addressInfo.description;
+ this.generatedId = addressInfo.generatedId;
+ this.addressId = addressInfo.addressId;
+ this.status = addressInfo.status;
+ this.usage = addressInfo.usage;
+ }
+
+ BuilderImpl(Address addressPb) {
+ if (RegionAddressId.matchesUrl(addressPb.getSelfLink())) {
+ addressId = RegionAddressId.fromUrl(addressPb.getSelfLink());
+ } else {
+ addressId = GlobalAddressId.fromUrl(addressPb.getSelfLink());
+ }
+ address = addressPb.getAddress();
+ if (addressPb.getCreationTimestamp() != null) {
+ creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(addressPb.getCreationTimestamp());
+ }
+ description = addressPb.getDescription();
+ if (addressPb.getId() != null) {
+ generatedId = addressPb.getId().toString();
+ }
+ if (addressPb.getStatus() != null) {
+ status = Status.valueOf(addressPb.getStatus());
+ }
+ if (addressPb.getUsers() != null && addressPb.getUsers().size() > 0) {
+ usage = Usage.fromPb(addressPb);
+ }
+ }
+
+ @Override
+ public BuilderImpl address(String address) {
+ this.address = address;
+ return this;
+ }
+
+ @Override
+ BuilderImpl creationTimestamp(Long creationTimestamp) {
+ this.creationTimestamp = creationTimestamp;
+ return this;
+ }
+
+ @Override
+ public BuilderImpl description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ @Override
+ BuilderImpl generatedId(String generatedId) {
+ this.generatedId = generatedId;
+ return this;
+ }
+
+ @Override
+ public BuilderImpl addressId(AddressId addressId) {
+ this.addressId = checkNotNull(addressId);
+ return this;
+ }
+
+ @Override
+ BuilderImpl status(Status status) {
+ this.status = status;
+ return this;
+ }
+
+ @Override
+ BuilderImpl usage(Usage usage) {
+ this.usage = usage;
+ return this;
+ }
+
+ @Override
+ public AddressInfo build() {
+ return new AddressInfo(this);
+ }
+ }
+
+ AddressInfo(BuilderImpl builder) {
+ address = builder.address;
+ creationTimestamp = builder.creationTimestamp;
+ description = builder.description;
+ generatedId = builder.generatedId;
+ addressId = checkNotNull(builder.addressId);
+ status = builder.status;
+ usage = builder.usage;
+ }
+
+ /**
+ * Returns the static external IP address represented by this object.
+ */
+ public String address() {
+ return address;
+ }
+
+ /**
+ * Returns the creation timestamp in milliseconds since epoch.
+ */
+ public Long creationTimestamp() {
+ return creationTimestamp;
+ }
+
+ /**
+ * Returns an optional textual description of the address.
+ */
+ public String description() {
+ return description;
+ }
+
+ /**
+ * Returns the service-generated unique identifier for the address.
+ */
+ public String generatedId() {
+ return generatedId;
+ }
+
+ /**
+ * Returns the address identity. Returns {@link GlobalAddressId} for a global address, returns
+ * {@link RegionAddressId} for a region address.
+ */
+ @SuppressWarnings("unchecked")
+ public T addressId() {
+ return (T) addressId;
+ }
+
+ /**
+ * Returns the status of the address.
+ */
+ public Status status() {
+ return status;
+ }
+
+ /**
+ * Returns the usage information of the address. Returns an {@link InstanceUsage} object for
+ * region addresses that are assigned to VM instances. Returns a {@link RegionForwardingUsage}
+ * object for region addresses assigned to region forwarding rules. Returns a
+ * {@link GlobalForwardingUsage} object for global addresses assigned to global forwarding rules.
+ * Returns {@code null} if the address is not in use.
+ */
+ @SuppressWarnings("unchecked")
+ public T usage() {
+ return (T) usage;
+ }
+
+ /**
+ * Returns a builder for the {@code AddressInfo} object.
+ */
+ public Builder toBuilder() {
+ return new BuilderImpl(this);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("address", address)
+ .add("creationTimestamp", creationTimestamp)
+ .add("description", description)
+ .add("generatedId", generatedId)
+ .add("addressId", addressId)
+ .add("status", status)
+ .add("usage", usage)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(address, creationTimestamp, description, generatedId, addressId, status,
+ usage);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this
+ || obj != null
+ && obj.getClass().equals(AddressInfo.class)
+ && Objects.equals(toPb(), ((AddressInfo) obj).toPb());
+ }
+
+ AddressInfo setProjectId(String projectId) {
+ if (addressId().project() != null) {
+ return this;
+ }
+ return toBuilder().addressId(addressId.setProjectId(projectId)).build();
+ }
+
+ Address toPb() {
+ Address addressPb = usage != null ? usage.toPb() : new Address();
+ addressPb.setAddress(address);
+ if (creationTimestamp != null) {
+ addressPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp));
+ }
+ addressPb.setDescription(description);
+ if (generatedId != null) {
+ addressPb.setId(new BigInteger(generatedId));
+ }
+ addressPb.setName(addressId.address());
+ if (addressId.type() == AddressId.Type.REGION) {
+ addressPb.setRegion(this.addressId().regionId().selfLink());
+ }
+ if (status != null) {
+ addressPb.setStatus(status.name());
+ }
+ addressPb.setSelfLink(addressId.selfLink());
+ return addressPb;
+ }
+
+ /**
+ * Returns a builder for the {@code AddressInfo} object given it's identity.
+ */
+ public static Builder builder(AddressId addressId) {
+ return new BuilderImpl().addressId(addressId);
+ }
+
+ /**
+ * Returns an {@code AddressInfo} object for the provided identity.
+ */
+ public static AddressInfo of(AddressId addressId) {
+ return builder(addressId).build();
+ }
+
+ /**
+ * Returns an {@code AddressInfo} object for the provided name. The object corresponds to a global
+ * address.
+ */
+ public static AddressInfo of(String name) {
+ return of(GlobalAddressId.of(name));
+ }
+
+ /**
+ * Returns an {@code AddressInfo} object for the provided region identity and name. The object
+ * corresponds to a region address.
+ */
+ public static AddressInfo of(RegionId regionId, String name) {
+ return of(RegionAddressId.of(regionId, name));
+ }
+
+ /**
+ * Returns an {@code AddressInfo} object for the provided region and address names. The object
+ * corresponds to a region address.
+ */
+ public static AddressInfo of(String region, String name) {
+ return of(RegionAddressId.of(region, name));
+ }
+
+ static AddressInfo fromPb(Address addressPb) {
+ return new BuilderImpl(addressPb).build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/AttachedDisk.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AttachedDisk.java
new file mode 100644
index 000000000000..d4ad674a8a5e
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AttachedDisk.java
@@ -0,0 +1,926 @@
+/*
+ * 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.cloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.api.services.compute.model.AttachedDiskInitializeParams;
+import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Lists;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A disk attached to a Google Compute Engine instance. To create a new disk to attach when an image
+ * is being created use {@link CreateDiskConfiguration}. To attach an existing persistent disk use
+ * {@link PersistentDiskConfiguration}. To attach a scratch disk use
+ * {@link ScratchDiskConfiguration}.
+ */
+public class AttachedDisk implements Serializable {
+
+ static final Function
+ FROM_PB_FUNCTION =
+ new Function() {
+ @Override
+ public AttachedDisk apply(
+ com.google.api.services.compute.model.AttachedDisk pb) {
+ return AttachedDisk.fromPb(pb);
+ }
+ };
+ static final Function
+ TO_PB_FUNCTION =
+ new Function() {
+ @Override
+ public com.google.api.services.compute.model.AttachedDisk apply(
+ AttachedDisk attachedDisk) {
+ return attachedDisk.toPb();
+ }
+ };
+ private static final long serialVersionUID = 2969789134157943798L;
+
+ private final String deviceName;
+ private final Integer index;
+ private final AttachedDiskConfiguration configuration;
+ private final List licenses;
+
+ /**
+ * Base class for {@code AttachedDisk} configuration. Use {@link PersistentDiskConfiguration} to
+ * attach an existing persistent disk. Use {@link CreateDiskConfiguration} to create a boot
+ * persistent disk to attach to the instance. Use {@link ScratchDiskConfiguration} to attach a
+ * scratch disk.
+ */
+ public abstract static class AttachedDiskConfiguration implements Serializable {
+
+ private static final long serialVersionUID = 8813134841283115565L;
+
+ private final Type type;
+ private final InterfaceType interfaceType;
+ private final Boolean boot;
+ private final Boolean autoDelete;
+
+ /**
+ * Specifies the type of the attached disk.
+ */
+ public enum Type {
+ /**
+ * A persistent disk attached to a VM instance. Such an attached disk must already exist or
+ * can be created along with the instance by using {@link CreateDiskConfiguration}. A
+ * persistent disk can be attached to other VM instances.
+ */
+ PERSISTENT,
+
+ /**
+ * A scratch disk is created with the VM instance it is attached to. Scratch disks are only
+ * available to their VM instance.
+ */
+ SCRATCH
+ }
+
+ /**
+ * Specifies the disk interface to use for attaching this disk, which is either {@code SCSI}
+ * or {@code NVME}. Persistent disks must always use {@code SCSI}. Scratch SSDs can use either
+ * {@code NVME} or {@code SCSI}.
+ */
+ public enum InterfaceType {
+ SCSI,
+ NVME
+ }
+
+ AttachedDiskConfiguration(Type type, InterfaceType interfaceType, Boolean boot,
+ Boolean autoDelete) {
+ this.type = checkNotNull(type);
+ this.interfaceType = interfaceType;
+ this.boot = boot;
+ this.autoDelete = autoDelete;
+ }
+
+ /**
+ * Returns the type of the attached disk.
+ */
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Returns the interface to use to attach the disk. If not specified, {@link InterfaceType#SCSI}
+ * is used.
+ */
+ public InterfaceType interfaceType() {
+ return interfaceType;
+ }
+
+ /**
+ * Returns whether to use the attached disk as a boot disk. If {@code true} the virtual machine
+ * will use the first partition of the disk for its root filesystem. If not specified, the
+ * disk is not used as a boot disk.
+ */
+ public Boolean boot() {
+ return boot;
+ }
+
+ /**
+ * Returns whether the disk should auto-delete when the instance to which it's attached is
+ * deleted. If not specified, the disk is not deleted automatically.
+ */
+ public Boolean autoDelete() {
+ return autoDelete;
+ }
+
+ MoreObjects.ToStringHelper toStringHelper() {
+ return MoreObjects.toStringHelper(this)
+ .add("type", type)
+ .add("interfaceType", interfaceType)
+ .add("boot", boot)
+ .add("autoDelete", autoDelete);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper().toString();
+ }
+
+ final int baseHashCode() {
+ return Objects.hash(type, interfaceType);
+ }
+
+ final boolean baseEquals(AttachedDiskConfiguration diskConfiguration) {
+ return Objects.equals(toPb(), diskConfiguration.toPb());
+ }
+
+ abstract AttachedDiskConfiguration setProjectId(String projectId);
+
+ com.google.api.services.compute.model.AttachedDisk toPb() {
+ com.google.api.services.compute.model.AttachedDisk attachedDiskPb =
+ new com.google.api.services.compute.model.AttachedDisk();
+ attachedDiskPb.setType(type.name());
+ if (interfaceType != null) {
+ attachedDiskPb.setInterface(interfaceType.name());
+ }
+ attachedDiskPb.setBoot(boot);
+ attachedDiskPb.setAutoDelete(autoDelete);
+ return attachedDiskPb;
+ }
+
+ @SuppressWarnings("unchecked")
+ static T fromPb(
+ com.google.api.services.compute.model.AttachedDisk diskPb) {
+ switch (Type.valueOf(diskPb.getType())) {
+ case PERSISTENT:
+ if (diskPb.getSource() == null) {
+ return (T) CreateDiskConfiguration.fromPb(diskPb);
+ } else {
+ return (T) PersistentDiskConfiguration.fromPb(diskPb);
+ }
+ case SCRATCH:
+ return (T) ScratchDiskConfiguration.fromPb(diskPb);
+ default:
+ // should be unreachable
+ throw new IllegalArgumentException("Unrecognized attached disk type");
+ }
+ }
+ }
+
+ /**
+ * An attached disk configuration for existing persistent disks.
+ */
+ public static final class PersistentDiskConfiguration extends AttachedDiskConfiguration {
+
+ private static final long serialVersionUID = 6367613188140104726L;
+
+ private final DiskId sourceDisk;
+ private final Mode mode;
+
+ /**
+ * Specifies the mode in which to attach the disk.
+ */
+ public enum Mode {
+ /**
+ * The instance can both read and write to the disk.
+ */
+ READ_WRITE,
+
+ /**
+ * The instance is only allowed to read the disk.
+ */
+ READ_ONLY
+ }
+
+ /**
+ * A builder for {@code PersistentDiskConfiguration} objects.
+ */
+ public static final class Builder {
+
+ private DiskId sourceDisk;
+ private Mode mode;
+ private Boolean boot;
+ private Boolean autoDelete;
+
+ private Builder(DiskId sourceDisk) {
+ this.sourceDisk = checkNotNull(sourceDisk);
+ }
+
+ private Builder(PersistentDiskConfiguration configuration) {
+ sourceDisk = configuration.sourceDisk;
+ mode = configuration.mode;
+ boot = configuration.boot();
+ autoDelete = configuration.autoDelete();
+ }
+
+ /**
+ * Sets the identity of the persistent disk to be attached.
+ */
+ public Builder sourceDisk(DiskId sourceDisk) {
+ this.sourceDisk = checkNotNull(sourceDisk);
+ return this;
+ }
+
+ /**
+ * Sets the mode in which to attach this disk. If not specified, the disk is attached in
+ * {@link Mode#READ_WRITE} mode.
+ */
+ public Builder mode(Mode mode) {
+ this.mode = mode;
+ return this;
+ }
+
+ /**
+ * Sets whether to use the attached disk as a boot disk. If {@code true} the virtual machine
+ * instance will use the first partition of the disk for its root filesystem. If not
+ * specified, the isk is not used as a boot disk.
+ */
+ public Builder boot(boolean boot) {
+ this.boot = boot;
+ return this;
+ }
+
+ /**
+ * Sets whether the disk should auto-delete when the instance to which it's attached is
+ * deleted. If not specified, the disk is not deleted automatically.
+ */
+ public Builder autoDelete(boolean autoDelete) {
+ this.autoDelete = autoDelete;
+ return this;
+ }
+
+ /**
+ * Creates a {@code PersistentDiskConfiguration} object.
+ */
+ public PersistentDiskConfiguration build() {
+ return new PersistentDiskConfiguration(this);
+ }
+ }
+
+ private PersistentDiskConfiguration(Builder builder) {
+ super(Type.PERSISTENT, null, builder.boot, builder.autoDelete);
+ this.sourceDisk = builder.sourceDisk;
+ this.mode = builder.mode;
+ }
+
+ /**
+ * Returns the identity of the persistent disk to be attached.
+ */
+ public DiskId sourceDisk() {
+ return sourceDisk;
+ }
+
+ /**
+ * Returns the mode in which to attach this disk. If not specified, the disk is attached in
+ * {@link Mode#READ_WRITE} mode.
+ */
+ public Mode mode() {
+ return mode;
+ }
+
+ /**
+ * Returns a builder for the current configuration.
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("sourceDisk", sourceDisk).add("mode", mode);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(baseHashCode(), sourceDisk, mode);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this
+ || obj != null
+ && obj.getClass().equals(PersistentDiskConfiguration.class)
+ && baseEquals((PersistentDiskConfiguration) obj);
+ }
+
+ @Override
+ PersistentDiskConfiguration setProjectId(String projectId) {
+ if (sourceDisk.project() != null) {
+ return this;
+ }
+ return toBuilder().sourceDisk(sourceDisk.setProjectId(projectId)).build();
+ }
+
+ @Override
+ com.google.api.services.compute.model.AttachedDisk toPb() {
+ com.google.api.services.compute.model.AttachedDisk attachedDiskPb = super.toPb();
+ attachedDiskPb.setSource(sourceDisk.selfLink());
+ attachedDiskPb.setMode(mode != null ? mode.toString() : null);
+ return attachedDiskPb;
+ }
+
+ /**
+ * Returns a builder for a {@code PersistentDiskConfiguration} object given the identity of the
+ * persistent disk to attach.
+ */
+ public static Builder builder(DiskId sourceDisk) {
+ return new Builder(sourceDisk);
+ }
+
+ /**
+ * Returns a {@code PersistentDiskConfiguration} object given the identity of the persistent
+ * disk to attach.
+ */
+ public static PersistentDiskConfiguration of(DiskId sourceDisk) {
+ return builder(sourceDisk).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ static PersistentDiskConfiguration fromPb(
+ com.google.api.services.compute.model.AttachedDisk diskPb) {
+ Builder builder = new Builder(DiskId.fromUrl(diskPb.getSource()));
+ if (diskPb.getMode() != null) {
+ builder.mode(Mode.valueOf(diskPb.getMode()));
+ }
+ if (diskPb.getBoot() != null) {
+ builder.boot(diskPb.getBoot());
+ }
+ if (diskPb.getAutoDelete() != null) {
+ builder.autoDelete(diskPb.getAutoDelete());
+ }
+ return builder.build();
+ }
+ }
+
+ /**
+ * An attached disk configuration for bootable persistent disks that must be created with the
+ * instance they are attached to. Attached disks that use this configuration can only be attached
+ * to an instance upon creation. A {@code CreateDiskConfiguration} object is never returned by the
+ * service: after the instance is created the corresponding attached disk will be returned with a
+ * {@link PersistentDiskConfiguration}.
+ */
+ public static final class CreateDiskConfiguration extends AttachedDiskConfiguration {
+
+ private static final long serialVersionUID = 961995522284348824L;
+
+ private final String diskName;
+ private final DiskTypeId diskType;
+ private final Long diskSizeGb;
+ private final ImageId sourceImage;
+
+ /**
+ * A builder for {@code CreateDiskConfiguration} objects.
+ */
+ public static final class Builder {
+
+ private String diskName;
+ private DiskTypeId diskType;
+ private Long diskSizeGb;
+ private ImageId sourceImage;
+ private Boolean autoDelete;
+
+ private Builder(ImageId sourceImage) {
+ this.sourceImage = checkNotNull(sourceImage);
+ }
+
+ private Builder(CreateDiskConfiguration configuration) {
+ this.diskName = configuration.diskName;
+ this.diskType = configuration.diskType;
+ this.diskSizeGb = configuration.diskSizeGb;
+ this.sourceImage = configuration.sourceImage;
+ this.autoDelete = configuration.autoDelete();
+ }
+
+ /**
+ * Sets the name to be assigned to the disk. If not specified, the disk is given the
+ * instance's name.
+ */
+ public Builder diskName(String diskName) {
+ this.diskName = diskName;
+ return this;
+ }
+
+ /**
+ * Sets the identity of the disk type. If not specified, {@code pd-standard} is used.
+ */
+ public Builder diskType(DiskTypeId diskType) {
+ this.diskType = diskType;
+ return this;
+ }
+
+ /**
+ * Sets the size of the persistent disk, in GB. If not set the disk will have the size of the
+ * source image. This value can be larger than the image's size. If the provided size is
+ * smaller than the image's size, then instance creation will fail.
+ */
+ public Builder diskSizeGb(Long diskSizeGb) {
+ this.diskSizeGb = diskSizeGb;
+ return this;
+ }
+
+ /**
+ * Sets the identity of the source image used to create the disk.
+ */
+ public Builder sourceImage(ImageId sourceImage) {
+ this.sourceImage = checkNotNull(sourceImage);
+ return this;
+ }
+
+ /**
+ * Sets whether the disk should auto-delete when the instance to which it's attached is
+ * deleted. If not specified, the disk is not deleted automatically.
+ */
+ public Builder autoDelete(Boolean autoDelete) {
+ this.autoDelete = autoDelete;
+ return this;
+ }
+
+ /**
+ * Creates a {@code CreateDiskConfiguration} object.
+ */
+ public CreateDiskConfiguration build() {
+ return new CreateDiskConfiguration(this);
+ }
+ }
+
+ private CreateDiskConfiguration(Builder builder) {
+ super(Type.PERSISTENT, null, true, builder.autoDelete);
+ this.diskName = builder.diskName;
+ this.diskType = builder.diskType;
+ this.diskSizeGb = builder.diskSizeGb;
+ this.sourceImage = builder.sourceImage;
+ }
+
+ /**
+ * Returns the name to be assigned to the disk. If not specified, the disk is given the
+ * instance's name.
+ */
+ public String diskName() {
+ return diskName;
+ }
+
+ /**
+ * Returns the identity of the disk type. If not specified, {@code pd-standard} is used.
+ */
+ public DiskTypeId diskType() {
+ return diskType;
+ }
+
+ /**
+ * Returns the size of the persistent disk, in GB. If not set the disk will have the size of the
+ * source image. This value can be larger than the image's size. If the provided size is smaller
+ * than the image's size then instance creation will fail.
+ */
+ public Long diskSizeGb() {
+ return diskSizeGb;
+ }
+
+ /**
+ * Returns the identity of the source image used to create the disk.
+ */
+ public ImageId sourceImage() {
+ return sourceImage;
+ }
+
+ /**
+ * Returns a builder for the current configuration.
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper()
+ .add("diskName", diskName)
+ .add("diskType", diskType)
+ .add("diskSizeGb", diskSizeGb)
+ .add("sourceImage", sourceImage);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(baseHashCode(), diskName, diskType, diskSizeGb, sourceImage);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this
+ || obj != null
+ && obj.getClass().equals(CreateDiskConfiguration.class)
+ && baseEquals((CreateDiskConfiguration) obj);
+ }
+
+ @Override
+ CreateDiskConfiguration setProjectId(String projectId) {
+ Builder builder = toBuilder();
+ if (builder.diskType != null) {
+ builder.diskType(diskType.setProjectId(projectId));
+ }
+ if (builder.sourceImage != null) {
+ builder.sourceImage(sourceImage.setProjectId(projectId));
+ }
+ return builder.build();
+ }
+
+ @Override
+ com.google.api.services.compute.model.AttachedDisk toPb() {
+ AttachedDiskInitializeParams initializeParamsPb = new AttachedDiskInitializeParams();
+ initializeParamsPb.setDiskName(diskName);
+ initializeParamsPb.setDiskSizeGb(diskSizeGb);
+ initializeParamsPb.setSourceImage(sourceImage.selfLink());
+ if (diskType != null) {
+ initializeParamsPb.setDiskType(diskType.selfLink());
+ }
+ com.google.api.services.compute.model.AttachedDisk attachedDiskPb = super.toPb();
+ attachedDiskPb.setInitializeParams(initializeParamsPb);
+ return attachedDiskPb;
+ }
+
+ /**
+ * Returns a builder for a {@code CreateDiskConfiguration} object given the source image that
+ * will be used to create the disk.
+ */
+ public static Builder builder(ImageId sourceImage) {
+ return new Builder(sourceImage);
+ }
+
+ /**
+ * Returns a {@code CreateDiskConfiguration} object given the source image that will be used to
+ * create the disk.
+ */
+ public static CreateDiskConfiguration of(ImageId sourceImage) {
+ return builder(sourceImage).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ static CreateDiskConfiguration fromPb(
+ com.google.api.services.compute.model.AttachedDisk diskPb) {
+ AttachedDiskInitializeParams initializeParamsPb = diskPb.getInitializeParams();
+ Builder builder = builder(ImageId.fromUrl(initializeParamsPb.getSourceImage()));
+ if (initializeParamsPb.getDiskType() != null) {
+ builder.diskType(DiskTypeId.fromUrl(initializeParamsPb.getDiskType()));
+ }
+ builder.diskName(initializeParamsPb.getDiskName());
+ builder.diskSizeGb(initializeParamsPb.getDiskSizeGb());
+ builder.autoDelete(diskPb.getAutoDelete());
+ if (initializeParamsPb.getDiskType() != null) {
+ builder.diskType(DiskTypeId.fromUrl(initializeParamsPb.getDiskType()));
+ }
+ return builder.build();
+ }
+ }
+
+ /**
+ * An attached disk configuration for scratch disks. Attached disks that use this configuration
+ * can only be attached to an instance upon creation.
+ */
+ public static final class ScratchDiskConfiguration extends AttachedDiskConfiguration {
+
+ private static final long serialVersionUID = -8445453507234691254L;
+
+ private final DiskTypeId diskType;
+
+ /**
+ * A builder for {@code ScratchDiskConfiguration} objects.
+ */
+ public static final class Builder {
+
+ private DiskTypeId diskType;
+ private InterfaceType interfaceType;
+
+ private Builder() {}
+
+ private Builder(ScratchDiskConfiguration configuration) {
+ this.diskType = configuration.diskType;
+ this.interfaceType = configuration.interfaceType();
+ }
+
+ /**
+ * Sets the identity of the disk type for the scratch disk to attach.
+ */
+ public Builder diskType(DiskTypeId diskType) {
+ this.diskType = diskType;
+ return this;
+ }
+
+ /**
+ * Sets the interface type. If not specified, {@code SCSI} is used.
+ */
+ public Builder interfaceType(InterfaceType interfaceType) {
+ this.interfaceType = interfaceType;
+ return this;
+ }
+
+ /**
+ * Creates a {@code ScratchDiskConfiguration} object.
+ */
+ public ScratchDiskConfiguration build() {
+ return new ScratchDiskConfiguration(this);
+ }
+ }
+
+ private ScratchDiskConfiguration(Builder builder) {
+ super(Type.SCRATCH, builder.interfaceType, false, true);
+ this.diskType = builder.diskType;
+ }
+
+ /**
+ * Returns the identity of the disk type for the scratch disk to attach.
+ */
+ public DiskTypeId diskType() {
+ return diskType;
+ }
+
+ /**
+ * Returns a builder for the current configuration.
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ MoreObjects.ToStringHelper toStringHelper() {
+ return super.toStringHelper().add("diskType", diskType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(baseHashCode());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this
+ || obj != null
+ && obj.getClass().equals(ScratchDiskConfiguration.class)
+ && baseEquals((ScratchDiskConfiguration) obj);
+ }
+
+ @Override
+ ScratchDiskConfiguration setProjectId(String projectId) {
+ if (diskType.project() != null) {
+ return this;
+ }
+ return toBuilder().diskType(diskType.setProjectId(projectId)).build();
+ }
+
+ @Override
+ com.google.api.services.compute.model.AttachedDisk toPb() {
+ com.google.api.services.compute.model.AttachedDisk attachedDiskPb = super.toPb();
+ if (diskType != null) {
+ AttachedDiskInitializeParams initializeParamsPb = new AttachedDiskInitializeParams();
+ initializeParamsPb.setDiskType(diskType.selfLink());
+ attachedDiskPb.setInitializeParams(initializeParamsPb);
+ }
+ return attachedDiskPb;
+ }
+
+ /**
+ * Returns a builder for {@code ScratchDiskConfiguration} objects given the disk type identity.
+ */
+ public static Builder builder(DiskTypeId diskType) {
+ return new Builder().diskType(diskType);
+ }
+
+ /**
+ * Returns a {@code ScratchDiskConfiguration} object given the disk type identity. The disk will
+ * be attached via the default interface ({@link InterfaceType#SCSI}).
+ */
+ public static ScratchDiskConfiguration of(DiskTypeId diskType) {
+ return builder(diskType).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ static ScratchDiskConfiguration fromPb(
+ com.google.api.services.compute.model.AttachedDisk diskPb) {
+ Builder builder = new Builder();
+ if (diskPb.getInterface() != null) {
+ builder.interfaceType(InterfaceType.valueOf(diskPb.getInterface()));
+ }
+ if (diskPb.getInitializeParams() != null
+ && diskPb.getInitializeParams().getDiskType() != null) {
+ builder.diskType(DiskTypeId.fromUrl(diskPb.getInitializeParams().getDiskType()));
+ }
+ return builder.build();
+ }
+ }
+
+ /**
+ * A builder for {@code AttachedDisk} objects.
+ */
+ public static final class Builder {
+
+ private String deviceName;
+ private Integer index;
+ private AttachedDiskConfiguration configuration;
+ private List licenses;
+
+ Builder(AttachedDiskConfiguration configuration) {
+ this.configuration = checkNotNull(configuration);
+ }
+
+ Builder(AttachedDisk attachedDisk) {
+ this.deviceName = attachedDisk.deviceName;
+ this.index = attachedDisk.index;
+ this.configuration = attachedDisk.configuration;
+ this.licenses = attachedDisk.licenses;
+ }
+
+ /**
+ * Sets the unique device name of your choice that is reflected into the
+ * {@code /dev/disk/by-id/google-*} tree of a Linux operating system running within the
+ * instance. This name can be used to reference the device for mounting, resizing, and so on,
+ * from within the instance. If not specified, the service chooses a default device name to
+ * apply to this disk, in the form {@code persistent-disks-x}, where x is a number assigned by
+ * Google Compute Engine.
+ */
+ public Builder deviceName(String deviceName) {
+ this.deviceName = deviceName;
+ return this;
+ }
+
+ /**
+ * Sets a zero-based index to this disk, where 0 is reserved for the boot disk. For example,
+ * if you have many disks attached to an instance, each disk would have an unique index number.
+ * If not specified, the service will choose an appropriate value.
+ */
+ public Builder index(Integer index) {
+ this.index = index;
+ return this;
+ }
+
+ /**
+ * Sets the attached disk configuration. Use {@link ScratchDiskConfiguration} to attach a
+ * scratch disk to the instance. Use {@link PersistentDiskConfiguration} to attach a
+ * persistent disk to the instance. Use {@link CreateDiskConfiguration} to create and attach
+ * a new persistent disk.
+ */
+ public Builder configuration(AttachedDiskConfiguration configuration) {
+ this.configuration = checkNotNull(configuration);
+ return this;
+ }
+
+ Builder licenses(List licenses) {
+ this.licenses = licenses;
+ return this;
+ }
+
+ /**
+ * Creates an {@code AttachedDisk} object.
+ */
+ public AttachedDisk build() {
+ return new AttachedDisk(this);
+ }
+ }
+
+ private AttachedDisk(Builder builder) {
+ this.deviceName = builder.deviceName;
+ this.index = builder.index;
+ this.configuration = builder.configuration;
+ this.licenses = builder.licenses;
+ }
+
+ /**
+ * Returns the unique device name of your choice that is reflected into the
+ * {@code /dev/disk/by-id/google-*} tree of a Linux operating system running within the
+ * instance. This name can be used to reference the device for mounting, resizing, and so on,
+ * from within the instance. If not specified, the service chooses a default device name to
+ * apply to this disk, in the form {@code persistent-disks-x}, where x is a number assigned by
+ * Google Compute Engine.
+ */
+ public String deviceName() {
+ return deviceName;
+ }
+
+ /**
+ * Returns a zero-based index to this disk, where 0 is reserved for the boot disk.
+ */
+ public Integer index() {
+ return index;
+ }
+
+ /**
+ * Returns the attached disk configuration. Returns {@link ScratchDiskConfiguration} to attach a
+ * scratch disk to the instance. Returns {@link PersistentDiskConfiguration} to attach a
+ * persistent disk to the instance. Returns {@link CreateDiskConfiguration} to create and attach
+ * a new persistent disk.
+ */
+ @SuppressWarnings("unchecked")
+ public T configuration() {
+ return (T) configuration;
+ }
+
+ /**
+ * Returns a list of publicly accessible licenses for the attached disk.
+ */
+ public List licenses() {
+ return licenses;
+ }
+
+ /**
+ * Returns a builder for the current attached disk.
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("deviceName", deviceName)
+ .add("index", index)
+ .add("configuration", configuration)
+ .add("licenses", licenses)
+ .toString();
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(deviceName, index, configuration, licenses);
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ return obj == this
+ || obj != null
+ && obj.getClass().equals(AttachedDisk.class)
+ && Objects.equals(toPb(), ((AttachedDisk) obj).toPb());
+ }
+
+ AttachedDisk setProjectId(String projectId) {
+ return toBuilder().configuration(configuration.setProjectId(projectId)).build();
+ }
+
+ com.google.api.services.compute.model.AttachedDisk toPb() {
+ com.google.api.services.compute.model.AttachedDisk attachedDiskPb = configuration.toPb();
+ attachedDiskPb.setDeviceName(deviceName);
+ attachedDiskPb.setIndex(index);
+ if (licenses != null) {
+ attachedDiskPb.setLicenses(Lists.transform(licenses, LicenseId.TO_URL_FUNCTION));
+ }
+ return attachedDiskPb;
+ }
+
+ /**
+ * Returns a builder for an {@code AttachedDisk} object given its configuration.
+ */
+ public static Builder builder(AttachedDiskConfiguration configuration) {
+ return new Builder(configuration).configuration(configuration);
+ }
+
+ /**
+ * Returns an {@code AttachedDisk} object given its configuration.
+ */
+ public static AttachedDisk of(AttachedDiskConfiguration configuration) {
+ return builder(configuration).build();
+ }
+
+ /**
+ * Returns an {@code AttachedDisk} object given the device name and its configuration.
+ */
+ public static AttachedDisk of(String deviceName, AttachedDiskConfiguration configuration) {
+ return builder(configuration).deviceName(deviceName).build();
+ }
+
+ static AttachedDisk fromPb(com.google.api.services.compute.model.AttachedDisk diskPb) {
+ AttachedDiskConfiguration configuration = AttachedDiskConfiguration.fromPb(diskPb);
+ Builder builder = builder(configuration);
+ builder.deviceName(diskPb.getDeviceName());
+ builder.index(diskPb.getIndex());
+ if (diskPb.getLicenses() != null) {
+ builder.licenses(Lists.transform(diskPb.getLicenses(), LicenseId.FROM_URL_FUNCTION));
+ }
+ return builder.build();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java
new file mode 100644
index 000000000000..47d594ba6ec5
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java
@@ -0,0 +1,2709 @@
+/*
+ * 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.cloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.cloud.FieldSelector;
+import com.google.cloud.FieldSelector.Helper;
+import com.google.cloud.Page;
+import com.google.cloud.Service;
+import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration;
+import com.google.cloud.compute.NetworkInterface.AccessConfig;
+import com.google.cloud.compute.spi.ComputeRpc;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * An interface for Google Cloud Compute Engine.
+ *
+ * @see Google Cloud Compute Engine
+ */
+public interface Compute extends Service {
+
+ /**
+ * Fields of a Compute Engine DiskType resource.
+ *
+ * @see Disk
+ * Type Resource
+ */
+ enum DiskTypeField implements FieldSelector {
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DEFAULT_DISK_SIZE_GB("defaultDiskSizeGb"),
+ DESCRIPTION("description"),
+ ID("id"),
+ NAME("name"),
+ SELF_LINK("selfLink"),
+ VALID_DISK_SIZE("validDiskSize"),
+ ZONE("zone"),
+ DEPRECATED("deprecated");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ DiskTypeField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine MachineType resource.
+ *
+ * @see
+ * Machine Type Resource
+ */
+ enum MachineTypeField implements FieldSelector {
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ GUEST_CPUS("guestCpus"),
+ ID("id"),
+ IMAGE_SPACE_GB("imageSpaceGb"),
+ MAXIMUM_PERSISTENT_DISKS("maximumPersistentDisks"),
+ MAXIMUM_PERSISTENT_DISKS_SIZE_GB("maximumPersistentDisksSizeGb"),
+ MEMORY_MB("memoryMb"),
+ NAME("name"),
+ SCRATCH_DISKS("scratchDisks"),
+ SELF_LINK("selfLink"),
+ ZONE("zone"),
+ DEPRECATED("deprecated");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ MachineTypeField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Region resource.
+ *
+ * @see
+ * Region Resource
+ */
+ enum RegionField implements FieldSelector {
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ ID("id"),
+ NAME("name"),
+ QUOTAS("quotas"),
+ SELF_LINK("selfLink"),
+ STATUS("status"),
+ ZONES("zones"),
+ DEPRECATED("deprecated");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ RegionField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Zone resource.
+ *
+ * @see Zone
+ * Resource
+ */
+ enum ZoneField implements FieldSelector {
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ ID("id"),
+ NAME("name"),
+ REGION("region"),
+ SELF_LINK("selfLink"),
+ STATUS("status"),
+ DEPRECATED("deprecated");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ ZoneField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine License resource.
+ *
+ * @see License
+ * Resource
+ */
+ enum LicenseField implements FieldSelector {
+ CHARGES_USE_FEE("chargesUseFee"),
+ NAME("name"),
+ SELF_LINK("selfLink");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ LicenseField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Operation resource.
+ *
+ * @see
+ * GlobalOperation Resource
+ * @see
+ * RegionOperation Resource
+ * @see
+ * ZoneOperation Resource
+ */
+ enum OperationField implements FieldSelector {
+ CLIENT_OPERATION_ID("clientOperationId"),
+ DESCRIPTION("description"),
+ END_TIME("endTime"),
+ ERROR("error"),
+ HTTP_ERROR_MESSAGE("httpErrorMessage"),
+ HTTP_ERROR_STATUS_CODE("httpErrorStatusCode"),
+ ID("id"),
+ INSERT_TIME("insertTime"),
+ NAME("name"),
+ OPERATION_TYPE("operationType"),
+ PROGRESS("progress"),
+ REGION("region"),
+ SELF_LINK("selfLink"),
+ START_TIME("startTime"),
+ STATUS("status"),
+ STATUS_MESSAGE("statusMessage"),
+ TARGET_ID("targetId"),
+ TARGET_LINK("targetLink"),
+ USER("user"),
+ WARNINGS("warnings"),
+ ZONE("zone");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ OperationField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Address resource.
+ *
+ * @see Region
+ * Address Resource
+ * @see
+ * Global Address Resource
+ */
+ enum AddressField implements FieldSelector {
+ ADDRESS("address"),
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ ID("id"),
+ NAME("name"),
+ REGION("region"),
+ SELF_LINK("selfLink"),
+ STATUS("status"),
+ USERS("users");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ AddressField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Disk resource.
+ *
+ * @see Disk
+ * Resource
+ */
+ enum DiskField implements FieldSelector {
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ ID("id"),
+ LAST_ATTACH_TIMESTAMP("lastAttachTimestamp"),
+ LAST_DETACH_TIMESTAMP("lastDetachTimestamp"),
+ LICENSES("licenses"),
+ NAME("name"),
+ OPTIONS("options"),
+ SELF_LINK("selfLink"),
+ SIZE_GB("sizeGb"),
+ SOURCE_IMAGE("sourceImage"),
+ SOURCE_IMAGE_ID("sourceImageId"),
+ SOURCE_SNAPSHOT("sourceSnapshot"),
+ SOURCE_SNAPSHOT_ID("sourceSnapshotId"),
+ STATUS("status"),
+ TYPE("type"),
+ USERS("users"),
+ ZONE("zone");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS =
+ ImmutableList.of(SELF_LINK, TYPE, SOURCE_IMAGE, SOURCE_SNAPSHOT);
+
+ private final String selector;
+
+ DiskField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Snapshot resource.
+ *
+ * @see
+ * Snapshot Resource
+ */
+ enum SnapshotField implements FieldSelector {
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ DISK_SIZE_GB("diskSizeGb"),
+ ID("id"),
+ LICENSES("licenses"),
+ NAME("name"),
+ SELF_LINK("selfLink"),
+ SOURCE_DISK("sourceDisk"),
+ SOURCE_DISK_ID("sourceDiskId"),
+ STATUS("status"),
+ STORAGE_BYTES("storageBytes"),
+ STORAGE_BYTES_STATUS("storageBytesStatus");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ SnapshotField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Image resource.
+ *
+ * @see Image
+ * Resource
+ */
+ enum ImageField implements FieldSelector {
+ ARCHIVE_SIZE_BYTES("archiveSizeBytes"),
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DEPRECATED("deprecated"),
+ DESCRIPTION("description"),
+ DISK_SIZE_GB("diskSizeGb"),
+ ID("id"),
+ LICENSES("licenses"),
+ NAME("name"),
+ RAW_DISK("rawDisk"),
+ SELF_LINK("selfLink"),
+ SOURCE_DISK("sourceDisk"),
+ SOURCE_DISK_ID("sourceDiskId"),
+ SOURCE_TYPE("sourceType");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS =
+ ImmutableList.of(SELF_LINK, SOURCE_DISK, RAW_DISK);
+
+ private final String selector;
+
+ ImageField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Subnetwork resource.
+ *
+ * @see
+ * Subnetwork Resource
+ */
+ enum SubnetworkField implements FieldSelector {
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ GATEWAY_ADDRESS("gatewayAddress"),
+ ID("id"),
+ IP_CIDR_RANGE("ipCidrRange"),
+ NAME("name"),
+ NETWORK("network"),
+ REGION("region"),
+ SELF_LINK("selfLink");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ SubnetworkField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Network resource.
+ *
+ * @see
+ * Network Resource
+ */
+ enum NetworkField implements FieldSelector {
+ IPV4_RANGE("IPv4Range"),
+ AUTO_CREATE_SUBNETWORKS("autoCreateSubnetworks"),
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ GATEWAY_IPV4("gatewayIPv4"),
+ ID("id"),
+ NAME("name"),
+ SELF_LINK("selfLink"),
+ SUBNETWORKS("subnetworks");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS =
+ ImmutableList.of(SELF_LINK, IPV4_RANGE, AUTO_CREATE_SUBNETWORKS);
+
+ private final String selector;
+
+ NetworkField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Fields of a Compute Engine Instance resource.
+ *
+ * @see
+ * Network Resource
+ */
+ enum InstanceField implements FieldSelector {
+ CAN_IP_FORWARD("canIpForward"),
+ CPU_PLATFORM("cpuPlatform"),
+ CREATION_TIMESTAMP("creationTimestamp"),
+ DESCRIPTION("description"),
+ DISKS("disks"),
+ ID("id"),
+ MACHINE_TYPE("machineType"),
+ METADATA("metadata"),
+ NAME("name"),
+ NETWORK_INTERFACES("networkInterfaces"),
+ SCHEDULING("scheduling"),
+ SELF_LINK("selfLink"),
+ SERVICE_ACCOUNTS("serviceAccounts"),
+ STATUS("status"),
+ STATUS_MESSAGE("statusMessage"),
+ TAGS("tags"),
+ ZONE("zone");
+
+ static final List extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(SELF_LINK);
+
+ private final String selector;
+
+ InstanceField(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public String selector() {
+ return selector;
+ }
+ }
+
+ /**
+ * Base class for list filters.
+ */
+ abstract class ListFilter implements Serializable {
+
+ private static final long serialVersionUID = -238638392811165127L;
+
+ private final String field;
+ private final ComparisonOperator operator;
+ private final Object value;
+
+ enum ComparisonOperator {
+ /**
+ * Defines an equals filter.
+ */
+ EQ,
+
+ /**
+ * Defines a not-equals filter.
+ */
+ NE
+ }
+
+ ListFilter(String field, ComparisonOperator operator, Object value) {
+ this.field = field;
+ this.operator = operator;
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(field, operator, value);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ListFilter && toPb().equals(((ListFilter) obj).toPb());
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("field", field)
+ .add("operator", operator)
+ .add("value", value)
+ .toString();
+ }
+
+ String toPb() {
+ return field + ' ' + operator.name().toLowerCase() + ' ' + value.toString();
+ }
+ }
+
+ /**
+ * Class for filtering disk type lists.
+ */
+ class DiskTypeFilter extends ListFilter {
+
+ private static final long serialVersionUID = 4847837203592234453L;
+
+ private DiskTypeFilter(DiskTypeField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static DiskTypeFilter equals(DiskTypeField field, String value) {
+ return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static DiskTypeFilter notEquals(DiskTypeField field, String value) {
+ return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns an equals filter for the given field and long value.
+ */
+ public static DiskTypeFilter equals(DiskTypeField field, long value) {
+ return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and long value.
+ */
+ public static DiskTypeFilter notEquals(DiskTypeField field, long value) {
+ return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.NE, value);
+ }
+ }
+
+ /**
+ * Class for filtering machine type lists.
+ */
+ class MachineTypeFilter extends ListFilter {
+
+ private static final long serialVersionUID = 7346062041571853235L;
+
+ private MachineTypeFilter(MachineTypeField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static MachineTypeFilter equals(MachineTypeField field, String value) {
+ return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static MachineTypeFilter notEquals(MachineTypeField field, String value) {
+ return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns an equals filter for the given field and long value.
+ */
+ public static MachineTypeFilter equals(MachineTypeField field, long value) {
+ return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and long value.
+ */
+ public static MachineTypeFilter notEquals(MachineTypeField field, long value) {
+ return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.NE, value);
+ }
+ }
+
+ /**
+ * Class for filtering region lists.
+ */
+ class RegionFilter extends ListFilter {
+
+ private static final long serialVersionUID = 4464892812442567172L;
+
+ private RegionFilter(RegionField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static RegionFilter equals(RegionField field, String value) {
+ return new RegionFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static RegionFilter notEquals(RegionField field, String value) {
+ return new RegionFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+ }
+
+ /**
+ * Class for filtering zone lists.
+ */
+ class ZoneFilter extends ListFilter {
+
+ private static final long serialVersionUID = -3927428278548808737L;
+
+ private ZoneFilter(ZoneField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static ZoneFilter equals(ZoneField field, String value) {
+ return new ZoneFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static ZoneFilter notEquals(ZoneField field, String value) {
+ return new ZoneFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+ }
+
+ /**
+ * Class for filtering operation lists.
+ */
+ class OperationFilter extends ListFilter {
+
+ private static final long serialVersionUID = -3202249202748346427L;
+
+ private OperationFilter(OperationField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static OperationFilter equals(OperationField field, String value) {
+ return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static OperationFilter notEquals(OperationField field, String value) {
+ return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns an equals filter for the given field and long value.
+ */
+ public static OperationFilter equals(OperationField field, long value) {
+ return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and long value.
+ */
+ public static OperationFilter notEquals(OperationField field, long value) {
+ return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, value);
+ }
+ }
+
+ /**
+ * Class for filtering address lists.
+ */
+ class AddressFilter extends ListFilter {
+
+ private static final long serialVersionUID = -227481644259653765L;
+
+ private AddressFilter(AddressField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static AddressFilter equals(AddressField field, String value) {
+ return new AddressFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static AddressFilter notEquals(AddressField field, String value) {
+ return new AddressFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+ }
+
+ /**
+ * Class for filtering snapshot lists.
+ */
+ class SnapshotFilter extends ListFilter {
+
+ private static final long serialVersionUID = 8757711630092406747L;
+
+ private SnapshotFilter(SnapshotField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static SnapshotFilter equals(SnapshotField field, String value) {
+ return new SnapshotFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static SnapshotFilter notEquals(SnapshotField field, String value) {
+ return new SnapshotFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns an equals filter for the given field and long value.
+ */
+ public static SnapshotFilter equals(SnapshotField field, long value) {
+ return new SnapshotFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and long value.
+ */
+ public static SnapshotFilter notEquals(SnapshotField field, long value) {
+ return new SnapshotFilter(checkNotNull(field), ComparisonOperator.NE, value);
+ }
+ }
+
+ /**
+ * Class for filtering image lists.
+ */
+ class ImageFilter extends ListFilter {
+
+ private static final long serialVersionUID = -3601427417234098397L;
+
+ private ImageFilter(ImageField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static ImageFilter equals(ImageField field, String value) {
+ return new ImageFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static ImageFilter notEquals(ImageField field, String value) {
+ return new ImageFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns an equals filter for the given field and long value.
+ */
+ public static ImageFilter equals(ImageField field, long value) {
+ return new ImageFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and long value.
+ */
+ public static ImageFilter notEquals(ImageField field, long value) {
+ return new ImageFilter(checkNotNull(field), ComparisonOperator.NE, value);
+ }
+ }
+
+ /**
+ * Class for filtering disk lists.
+ */
+ class DiskFilter extends ListFilter {
+
+ private static final long serialVersionUID = 5856790665396877913L;
+
+ private DiskFilter(DiskField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static DiskFilter equals(DiskField field, String value) {
+ return new DiskFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static DiskFilter notEquals(DiskField field, String value) {
+ return new DiskFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns an equals filter for the given field and long value.
+ */
+ public static DiskFilter equals(DiskField field, long value) {
+ return new DiskFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and long value.
+ */
+ public static DiskFilter notEquals(DiskField field, long value) {
+ return new DiskFilter(checkNotNull(field), ComparisonOperator.NE, value);
+ }
+ }
+
+ /**
+ * Class for filtering subnetwork lists.
+ */
+ class SubnetworkFilter extends ListFilter {
+
+ private static final long serialVersionUID = 979448583739105481L;
+
+ private SubnetworkFilter(SubnetworkField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static SubnetworkFilter equals(SubnetworkField field, String value) {
+ return new SubnetworkFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static SubnetworkFilter notEquals(SubnetworkField field, String value) {
+ return new SubnetworkFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+ }
+
+ /**
+ * Class for filtering network lists.
+ */
+ class NetworkFilter extends ListFilter {
+
+ private static final long serialVersionUID = 7921406498804130930L;
+
+ private NetworkFilter(NetworkField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static NetworkFilter equals(NetworkField field, String value) {
+ return new NetworkFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static NetworkFilter notEquals(NetworkField field, String value) {
+ return new NetworkFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns a equals filter for the given field and boolean value.
+ */
+ public static NetworkFilter equals(NetworkField field, boolean value) {
+ return new NetworkFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and boolean value.
+ */
+ public static NetworkFilter notEquals(NetworkField field, boolean value) {
+ return new NetworkFilter(checkNotNull(field), ComparisonOperator.NE, value);
+ }
+ }
+
+ /**
+ * Class for filtering instance lists.
+ */
+ class InstanceFilter extends ListFilter {
+
+ private static final long serialVersionUID = 679008888882025686L;
+
+ private InstanceFilter(InstanceField field, ComparisonOperator operator, Object value) {
+ super(field.selector(), operator, value);
+ }
+
+ /**
+ * Returns an equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static InstanceFilter equals(InstanceField field, String value) {
+ return new InstanceFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and string value. For string fields,
+ * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
+ * match the entire field.
+ *
+ * @see RE2
+ */
+ public static InstanceFilter notEquals(InstanceField field, String value) {
+ return new InstanceFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
+ }
+
+ /**
+ * Returns a equals filter for the given field and boolean value.
+ */
+ public static InstanceFilter equals(InstanceField field, boolean value) {
+ return new InstanceFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+
+ /**
+ * Returns a not-equals filter for the given field and boolean value.
+ */
+ public static InstanceFilter notEquals(InstanceField field, boolean value) {
+ return new InstanceFilter(checkNotNull(field), ComparisonOperator.EQ, value);
+ }
+ }
+
+ /**
+ * Class for specifying disk type get options.
+ */
+ class DiskTypeOption extends Option {
+
+ private static final long serialVersionUID = 7349162455602991554L;
+
+ private DiskTypeOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the disk type's fields to be returned by the RPC call. If this
+ * option is not provided, all disk type's fields are returned. {@code DiskTypeOption.fields}
+ * can be used to specify only the fields of interest. {@link DiskType#diskTypeId()} is always
+ * returned, even if not specified.
+ */
+ public static DiskTypeOption fields(DiskTypeField... fields) {
+ return new DiskTypeOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(DiskTypeField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying disk type list options.
+ */
+ class DiskTypeListOption extends Option {
+
+ private static final long serialVersionUID = 9051194230847610951L;
+
+ private DiskTypeListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the disk types being listed.
+ */
+ public static DiskTypeListOption filter(DiskTypeFilter filter) {
+ return new DiskTypeListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of disk types returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static DiskTypeListOption pageSize(long pageSize) {
+ return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing disk types.
+ */
+ public static DiskTypeListOption pageToken(String pageToken) {
+ return new DiskTypeListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the disk type's fields to be returned by the RPC call. If this
+ * option is not provided, all disk type's fields are returned.
+ * {@code DiskTypeListOption.fields} can be used to specify only the fields of interest.
+ * {@link DiskType#diskTypeId()} is always returned, even if not specified.
+ */
+ public static DiskTypeListOption fields(DiskTypeField... fields) {
+ return new DiskTypeListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", DiskTypeField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying disk type aggregated list options.
+ */
+ class DiskTypeAggregatedListOption extends Option {
+
+ private static final long serialVersionUID = 7611137483018305170L;
+
+ private DiskTypeAggregatedListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the disk types being listed.
+ */
+ public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) {
+ return new DiskTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of disk types returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static DiskTypeAggregatedListOption pageSize(long pageSize) {
+ return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing disk types.
+ */
+ public static DiskTypeAggregatedListOption pageToken(String pageToken) {
+ return new DiskTypeAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+ }
+
+ /**
+ * Class for specifying machine type get options.
+ */
+ class MachineTypeOption extends Option {
+
+ private static final long serialVersionUID = 7349162455602991554L;
+
+ private MachineTypeOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the machine type's fields to be returned by the RPC call. If
+ * this option is not provided, all machine type's fields are returned.
+ * {@code MachineTypeOption.fields} can be used to specify only the fields of interest.
+ * {@link MachineType#machineTypeId()} is always returned, even if not specified.
+ */
+ public static MachineTypeOption fields(MachineTypeField... fields) {
+ return new MachineTypeOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(MachineTypeField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying machine type list options.
+ */
+ class MachineTypeListOption extends Option {
+
+ private static final long serialVersionUID = -2974553049419897902L;
+
+ private MachineTypeListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the machine types being listed.
+ */
+ public static MachineTypeListOption filter(MachineTypeFilter filter) {
+ return new MachineTypeListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of machine types returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static MachineTypeListOption pageSize(long pageSize) {
+ return new MachineTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing machine types.
+ */
+ public static MachineTypeListOption pageToken(String pageToken) {
+ return new MachineTypeListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the machine type's fields to be returned by the RPC call. If
+ * this option is not provided, all machine type's fields are returned.
+ * {@code MachineTypeListOption.fields} can be used to specify only the fields of interest.
+ * {@link MachineType#machineTypeId()} is always returned, even if not specified.
+ */
+ public static MachineTypeListOption fields(MachineTypeField... fields) {
+ return new MachineTypeListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", MachineTypeField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying machine type aggregated list options.
+ */
+ class MachineTypeAggregatedListOption extends Option {
+
+ private static final long serialVersionUID = 8492257475500296057L;
+
+ private MachineTypeAggregatedListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the machine types being listed.
+ */
+ public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) {
+ return new MachineTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of machine types returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static MachineTypeAggregatedListOption pageSize(long pageSize) {
+ return new MachineTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing machine types.
+ */
+ public static MachineTypeAggregatedListOption pageToken(String pageToken) {
+ return new MachineTypeAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+ }
+
+ /**
+ * Class for specifying region get options.
+ */
+ class RegionOption extends Option {
+
+ private static final long serialVersionUID = 2025084807788610826L;
+
+ private RegionOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the region's fields to be returned by the RPC call. If this
+ * option is not provided, all region's fields are returned. {@code RegionOption.fields} can be
+ * used to specify only the fields of interest. {@link Region#regionId()} is always
+ * returned, even if not specified.
+ */
+ public static RegionOption fields(RegionField... fields) {
+ return new RegionOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(RegionField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying region list options.
+ */
+ class RegionListOption extends Option {
+
+ private static final long serialVersionUID = 3348089279267170211L;
+
+ private RegionListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the regions being listed.
+ */
+ public static RegionListOption filter(RegionFilter filter) {
+ return new RegionListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of regions returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static RegionListOption pageSize(long pageSize) {
+ return new RegionListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing regions.
+ */
+ public static RegionListOption pageToken(String pageToken) {
+ return new RegionListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the region's fields to be returned by the RPC call. If this
+ * option is not provided, all region's fields are returned. {@code RegionListOption.fields} can
+ * be used to specify only the fields of interest. {@link Region#regionId()} is always
+ * returned, even if not specified.
+ */
+ public static RegionListOption fields(RegionField... fields) {
+ return new RegionListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", RegionField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying zone get options.
+ */
+ class ZoneOption extends Option {
+
+ private static final long serialVersionUID = -2968652076389846258L;
+
+ private ZoneOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the zone's fields to be returned by the RPC call. If this option
+ * is not provided, all zone's fields are returned. {@code ZoneOption.fields} can be used to
+ * specify only the fields of interest. {@link Zone#zoneId()} is always returned, even if
+ * not specified.
+ */
+ public static ZoneOption fields(ZoneField... fields) {
+ return new ZoneOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(ZoneField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying zone list options.
+ */
+ class ZoneListOption extends Option {
+
+ private static final long serialVersionUID = -4721971371200905764L;
+
+ private ZoneListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the zones being listed.
+ */
+ public static ZoneListOption filter(ZoneFilter filter) {
+ return new ZoneListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of zones returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static ZoneListOption pageSize(long pageSize) {
+ return new ZoneListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing zones.
+ */
+ public static ZoneListOption pageToken(String pageToken) {
+ return new ZoneListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the zone's fields to be returned by the RPC call. If this option
+ * is not provided, all zone's fields are returned. {@code ZoneListOption.fields} can be used to
+ * specify only the fields of interest. {@link Zone#zoneId()} is always returned, even if
+ * not specified.
+ */
+ public static ZoneListOption fields(ZoneField... fields) {
+ return new ZoneListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", ZoneField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying license get options.
+ */
+ class LicenseOption extends Option {
+
+ private static final long serialVersionUID = -2968652076389846258L;
+
+ private LicenseOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the license's fields to be returned by the RPC call. If this
+ * option is not provided, all license's fields are returned. {@code LicenseOption.fields} can
+ * be used to specify only the fields of interest. {@link License#licenseId()} is always
+ * returned, even if not specified.
+ */
+ public static LicenseOption fields(LicenseField... fields) {
+ return new LicenseOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(LicenseField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying operation get options.
+ */
+ class OperationOption extends Option {
+
+ private static final long serialVersionUID = -4572636917684779912L;
+
+ private OperationOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the operation's fields to be returned by the RPC call. If this
+ * option is not provided, all operation's fields are returned. {@code OperationOption.fields}
+ * can be used to specify only the fields of interest. {@link Operation#operationId()} is
+ * always returned, even if not specified.
+ */
+ public static OperationOption fields(OperationField... fields) {
+ return new OperationOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(OperationField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying operation list options.
+ */
+ class OperationListOption extends Option {
+
+ private static final long serialVersionUID = -1509532420587265823L;
+
+ private OperationListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the operations being listed.
+ */
+ public static OperationListOption filter(OperationFilter filter) {
+ return new OperationListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of operations returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static OperationListOption pageSize(long pageSize) {
+ return new OperationListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing operations.
+ */
+ public static OperationListOption pageToken(String pageToken) {
+ return new OperationListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the operation's fields to be returned by the RPC call. If this
+ * option is not provided, all operation's fields are returned.
+ * {@code OperationListOption.fields} can be used to specify only the fields of interest.
+ * {@link Operation#operationId()} is always returned, even if not specified.
+ */
+ public static OperationListOption fields(OperationField... fields) {
+ return new OperationListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", OperationField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying address get options.
+ */
+ class AddressOption extends Option {
+
+ private static final long serialVersionUID = -5755491818692494389L;
+
+ private AddressOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the address' fields to be returned by the RPC call. If this
+ * option is not provided, all address' fields are returned. {@code AddressOption.fields} can be
+ * used to specify only the fields of interest. {@link Address#addressId()} is always
+ * returned, even if not specified.
+ */
+ public static AddressOption fields(AddressField... fields) {
+ return new AddressOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(AddressField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying address list options.
+ */
+ class AddressListOption extends Option {
+
+ private static final long serialVersionUID = -4281322966374929346L;
+
+ private AddressListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the addresses being listed.
+ */
+ public static AddressListOption filter(AddressFilter filter) {
+ return new AddressListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of addresses returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static AddressListOption pageSize(long pageSize) {
+ return new AddressListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing addresses.
+ */
+ public static AddressListOption pageToken(String pageToken) {
+ return new AddressListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the address' fields to be returned by the RPC call. If this
+ * option is not provided, all address' fields are returned. {@code AddressListOption.fields}
+ * can be used to specify only the fields of interest. {@link Address#addressId()} is always
+ * returned, even if not specified.
+ */
+ public static AddressListOption fields(AddressField... fields) {
+ return new AddressListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", AddressField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying address aggregated list options.
+ */
+ class AddressAggregatedListOption extends Option {
+
+ private static final long serialVersionUID = -95538941541279561L;
+
+ private AddressAggregatedListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the addresses being listed.
+ */
+ public static AddressAggregatedListOption filter(AddressFilter filter) {
+ return new AddressAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of addresses returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static AddressAggregatedListOption pageSize(long pageSize) {
+ return new AddressAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing addresses.
+ */
+ public static AddressAggregatedListOption pageToken(String pageToken) {
+ return new AddressAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+ }
+
+ /**
+ * Class for specifying snapshot get options.
+ */
+ class SnapshotOption extends Option {
+
+ private static final long serialVersionUID = -3505179459035500945L;
+
+ private SnapshotOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the snapshot's fields to be returned by the RPC call. If this
+ * option is not provided, all the snapshot's fields are returned. {@code SnapshotOption.fields}
+ * can be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always
+ * returned, even if not specified.
+ */
+ public static SnapshotOption fields(SnapshotField... fields) {
+ return new SnapshotOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(SnapshotField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying snapshot list options.
+ */
+ class SnapshotListOption extends Option {
+
+ private static final long serialVersionUID = 8278588147660831257L;
+
+ private SnapshotListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the snapshots being listed.
+ */
+ public static SnapshotListOption filter(SnapshotFilter filter) {
+ return new SnapshotListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of snapshots returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static SnapshotListOption pageSize(long pageSize) {
+ return new SnapshotListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing snapshots.
+ */
+ public static SnapshotListOption pageToken(String pageToken) {
+ return new SnapshotListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the snapshot's fields to be returned by the RPC call. If this
+ * option is not provided, all the snapshot's fields are returned.
+ * {@code SnapshotListOption.fields} can be used to specify only the fields of interest.
+ * {@link Snapshot#snapshotId()} is always returned, even if not specified.
+ */
+ public static SnapshotListOption fields(SnapshotField... fields) {
+ return new SnapshotListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", SnapshotField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying image get options.
+ */
+ class ImageOption extends Option {
+
+ private static final long serialVersionUID = -7622190783089299272L;
+
+ private ImageOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the image's fields to be returned by the RPC call. If this
+ * option is not provided, all image's fields are returned. {@code ImageOption.fields} can be
+ * used to specify only the fields of interest. {@link Image#imageId()} and
+ * {@link Image#configuration()} are always returned, even if not specified.
+ */
+ public static ImageOption fields(ImageField... fields) {
+ return new ImageOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(ImageField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying image list options.
+ */
+ class ImageListOption extends Option {
+
+ private static final long serialVersionUID = -4927977224287915654L;
+
+ private ImageListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the images being listed.
+ */
+ public static ImageListOption filter(ImageFilter filter) {
+ return new ImageListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of images returned per page. {@code pageSize}
+ * must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static ImageListOption pageSize(long pageSize) {
+ return new ImageListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing images.
+ */
+ public static ImageListOption pageToken(String pageToken) {
+ return new ImageListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the image's fields to be returned by the RPC call. If this
+ * option is not provided, all image's fields are returned. {@code ImageListOption.fields} can
+ * be used to specify only the fields of interest. {@link Image#imageId()} and
+ * {@link Image#configuration()} are always returned, even if not specified.
+ */
+ public static ImageListOption fields(ImageField... fields) {
+ return new ImageListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", ImageField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying disk get options.
+ */
+ class DiskOption extends Option {
+
+ private static final long serialVersionUID = -4354796876226661667L;
+
+ private DiskOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the disk's fields to be returned by the RPC call. If this option
+ * is not provided, all disk's fields are returned. {@code DiskOption.fields} can be used to
+ * specify only the fields of interest. {@link Disk#diskId()},
+ * {@link DiskConfiguration#diskType()} and either
+ * {@link SnapshotDiskConfiguration#sourceSnapshot()} or
+ * {@link ImageDiskConfiguration#sourceImage()} are always returned, even if not specified.
+ */
+ public static DiskOption fields(DiskField... fields) {
+ return new DiskOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(DiskField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying disk list options.
+ */
+ class DiskListOption extends Option {
+
+ private static final long serialVersionUID = -5148497888688645905L;
+
+ private DiskListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the disks being listed.
+ */
+ public static DiskListOption filter(DiskFilter filter) {
+ return new DiskListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of disks returned per page. {@code pageSize}
+ * must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static DiskListOption pageSize(long pageSize) {
+ return new DiskListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing disks.
+ */
+ public static DiskListOption pageToken(String pageToken) {
+ return new DiskListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the disk's fields to be returned by the RPC call. If this option
+ * is not provided, all disk's fields are returned. {@code DiskListOption.fields} can be used to
+ * specify only the fields of interest. {@link Disk#diskId()},
+ * {@link DiskConfiguration#diskType()} and either
+ * {@link SnapshotDiskConfiguration#sourceSnapshot()} or
+ * {@link ImageDiskConfiguration#sourceImage()} are always returned, even if not specified.
+ */
+ public static DiskListOption fields(DiskField... fields) {
+ return new DiskListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", DiskField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying disk aggregated list options.
+ */
+ class DiskAggregatedListOption extends Option {
+
+ private static final long serialVersionUID = 1163784797870242766L;
+
+ private DiskAggregatedListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the disks being listed.
+ */
+ public static DiskAggregatedListOption filter(DiskFilter filter) {
+ return new DiskAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of disks returned per page. {@code pageSize}
+ * must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static DiskAggregatedListOption pageSize(long pageSize) {
+ return new DiskAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing disks.
+ */
+ public static DiskAggregatedListOption pageToken(String pageToken) {
+ return new DiskAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+ }
+
+ /**
+ * Class for specifying subnetwork get options.
+ */
+ class SubnetworkOption extends Option {
+
+ private static final long serialVersionUID = 1994416967962074717L;
+
+ private SubnetworkOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the subnetwork's fields to be returned by the RPC call. If this
+ * option is not provided, all subnetwork's fields are returned. {@code SubnetworkOption.fields}
+ * can be used to specify only the fields of interest. {@link Subnetwork#subnetworkId()} is
+ * always returned, even if not specified.
+ */
+ public static SubnetworkOption fields(SubnetworkField... fields) {
+ return new SubnetworkOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(SubnetworkField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying subnetwork list options.
+ */
+ class SubnetworkListOption extends Option {
+
+ private static final long serialVersionUID = -2978666213373829606L;
+
+ private SubnetworkListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the subnetworks being listed.
+ */
+ public static SubnetworkListOption filter(SubnetworkFilter filter) {
+ return new SubnetworkListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of subnetworks returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static SubnetworkListOption pageSize(long pageSize) {
+ return new SubnetworkListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing subnetworks.
+ */
+ public static SubnetworkListOption pageToken(String pageToken) {
+ return new SubnetworkListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the subnetwork's fields to be returned by the RPC call. If this
+ * option is not provided, all subnetwork's fields are returned.
+ * {@code SubnetworListkOption.fields} can be used to specify only the fields of interest.
+ * {@link Subnetwork#subnetworkId()} is always returned, even if not specified.
+ */
+ public static SubnetworkListOption fields(SubnetworkField... fields) {
+ return new SubnetworkListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", SubnetworkField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying subnetwork aggregated list options.
+ */
+ class SubnetworkAggregatedListOption extends Option {
+
+ private static final long serialVersionUID = -4033514850525545027L;
+
+ private SubnetworkAggregatedListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the subnetworks being listed.
+ */
+ public static SubnetworkAggregatedListOption filter(SubnetworkFilter filter) {
+ return new SubnetworkAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of subnetworks returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static SubnetworkAggregatedListOption pageSize(long pageSize) {
+ return new SubnetworkAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing subnetworks.
+ */
+ public static SubnetworkAggregatedListOption pageToken(String pageToken) {
+ return new SubnetworkAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+ }
+
+ /**
+ * Class for specifying network get options.
+ */
+ class NetworkOption extends Option {
+
+ private static final long serialVersionUID = 5346750551643875754L;
+
+ private NetworkOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the network's fields to be returned by the RPC call. If this
+ * option is not provided, all network's fields are returned. {@code NetworkOption.fields}
+ * can be used to specify only the fields of interest. {@link Network#networkId()} and
+ * {@link Network#configuration()} are always returned, even if not specified.
+ */
+ public static NetworkOption fields(NetworkField... fields) {
+ return new NetworkOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(NetworkField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying network list options.
+ */
+ class NetworkListOption extends Option {
+
+ private static final long serialVersionUID = -4291731916527773896L;
+
+ private NetworkListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the networks being listed.
+ */
+ public static NetworkListOption filter(NetworkFilter filter) {
+ return new NetworkListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of networks returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static NetworkListOption pageSize(long pageSize) {
+ return new NetworkListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing networks.
+ */
+ public static NetworkListOption pageToken(String pageToken) {
+ return new NetworkListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the network's fields to be returned by the RPC call. If this
+ * option is not provided, all network's fields are returned. {@code NetworkListOption.fields}
+ * can be used to specify only the fields of interest. {@link Network#networkId()} and
+ * {@link Network#configuration()} are always returned, even if not specified.
+ */
+ public static NetworkListOption fields(NetworkField... fields) {
+ return new NetworkListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", NetworkField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying instance get options.
+ */
+ class InstanceOption extends Option {
+
+ private static final long serialVersionUID = -5277658025892081493L;
+
+ private InstanceOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify the instance's fields to be returned by the RPC call. If this
+ * option is not provided, all instance's fields are returned. {@code InstanceOption.fields}
+ * can be used to specify only the fields of interest. {@link Instance#instanceId()} is always
+ * returned, even if not specified.
+ */
+ public static InstanceOption fields(InstanceField... fields) {
+ return new InstanceOption(ComputeRpc.Option.FIELDS,
+ Helper.selector(InstanceField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying instance list options.
+ */
+ class InstanceListOption extends Option {
+
+ private static final long serialVersionUID = -1096684312959047430L;
+
+ private InstanceListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the instances being listed.
+ */
+ public static InstanceListOption filter(InstanceFilter filter) {
+ return new InstanceListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of instances returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static InstanceListOption pageSize(long pageSize) {
+ return new InstanceListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing instances.
+ */
+ public static InstanceListOption pageToken(String pageToken) {
+ return new InstanceListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+
+ /**
+ * Returns an option to specify the instance's fields to be returned by the RPC call. If this
+ * option is not provided, all instance's fields are returned. {@code InstanceListOption.fields}
+ * can be used to specify only the fields of interest. {@link Instance#instanceId()} is always
+ * returned, even if not specified.
+ */
+ public static InstanceListOption fields(InstanceField... fields) {
+ return new InstanceListOption(ComputeRpc.Option.FIELDS,
+ Helper.listSelector("items", InstanceField.REQUIRED_FIELDS, fields));
+ }
+ }
+
+ /**
+ * Class for specifying instance aggregated list options.
+ */
+ class InstanceAggregatedListOption extends Option {
+
+ private static final long serialVersionUID = -2020005298975967713L;
+
+ private InstanceAggregatedListOption(ComputeRpc.Option option, Object value) {
+ super(option, value);
+ }
+
+ /**
+ * Returns an option to specify a filter on the instances being listed.
+ */
+ public static InstanceAggregatedListOption filter(InstanceFilter filter) {
+ return new InstanceAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
+ }
+
+ /**
+ * Returns an option to specify the maximum number of instances returned per page.
+ * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used.
+ */
+ public static InstanceAggregatedListOption pageSize(long pageSize) {
+ return new InstanceAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
+ }
+
+ /**
+ * Returns an option to specify the page token from which to start listing instances.
+ */
+ public static InstanceAggregatedListOption pageToken(String pageToken) {
+ return new InstanceAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
+ }
+ }
+
+ /**
+ * Returns the requested disk type or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ DiskType getDiskType(DiskTypeId diskTypeId, DiskTypeOption... options);
+
+ /**
+ * Returns the requested disk type or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ DiskType getDiskType(String zone, String diskType, DiskTypeOption... options);
+
+ /**
+ * Lists the disk types in the provided zone.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listDiskTypes(String zone, DiskTypeListOption... options);
+
+ /**
+ * Lists the disk types in all zones.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listDiskTypes(DiskTypeAggregatedListOption... options);
+
+ /**
+ * Returns the requested machine type or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ MachineType getMachineType(MachineTypeId machineTypeId, MachineTypeOption... options);
+
+ /**
+ * Returns the requested machine type or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ MachineType getMachineType(String zone, String machineType, MachineTypeOption... options);
+
+ /**
+ * Lists the machine types in the provided zone.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listMachineTypes(String zone, MachineTypeListOption... options);
+
+ /**
+ * Lists the machine types in all zones.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listMachineTypes(MachineTypeAggregatedListOption... options);
+
+ /**
+ * Returns the requested region or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Region getRegion(String region, RegionOption... options);
+
+ /**
+ * Lists the regions.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listRegions(RegionListOption... options);
+
+ /**
+ * Returns the requested zone or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Zone getZone(String zone, ZoneOption... options);
+
+ /**
+ * Lists the zones.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listZones(ZoneListOption... options);
+
+ /**
+ * Returns the requested license or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ License getLicense(String license, LicenseOption... options);
+
+ /**
+ * Returns the requested license or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ License getLicense(LicenseId license, LicenseOption... options);
+
+ /**
+ * Returns the requested operation or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Operation getOperation(OperationId operationId, OperationOption... options);
+
+ /**
+ * Lists the global operations.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listGlobalOperations(OperationListOption... options);
+
+ /**
+ * Lists the operations for the provided region. These are operations that create/modify/delete
+ * resources that live in a region (e.g. subnetworks).
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listRegionOperations(String region, OperationListOption... options);
+
+ /**
+ * Lists the operations for the provided zone. These are operations that create/modify/delete
+ * resources that live in a zone (e.g. instances).
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listZoneOperations(String zone, OperationListOption... options);
+
+ /**
+ * Deletes the requested operation. Delete is only possible for operations that have completed
+ * their execution. Any attempt to delete a running operation will fail.
+ *
+ * @return {@code true} if operation was deleted, {@code false} if it was not found
+ * @throws ComputeException upon failure
+ */
+ boolean deleteOperation(OperationId operation);
+
+ /**
+ * Returns the requested address or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Address getAddress(AddressId addressId, AddressOption... options);
+
+ /**
+ * Creates a new address.
+ *
+ * @return an operation for address' creation
+ * @throws ComputeException upon failure
+ */
+ Operation create(AddressInfo address, OperationOption... options);
+
+ /**
+ * Lists the global addresses.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listGlobalAddresses(AddressListOption... options);
+
+ /**
+ * Lists the region addresses for the provided region.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listRegionAddresses(String region, AddressListOption... options);
+
+ /**
+ * Lists both global and region addresses.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listAddresses(AddressAggregatedListOption... options);
+
+ /**
+ * Deletes the requested address.
+ *
+ * @return an operation if the request was issued correctly, {@code null} if the address was not
+ * found
+ * @throws ComputeException upon failure
+ */
+ Operation deleteAddress(AddressId addressId, OperationOption... options);
+
+ /**
+ * Creates a new snapshot.
+ *
+ * @return a zone operation for snapshot creation
+ * @throws ComputeException upon failure
+ */
+ Operation create(SnapshotInfo snapshot, OperationOption... options);
+
+ /**
+ * Returns the requested snapshot or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Snapshot getSnapshot(String snapshot, SnapshotOption... options);
+
+ /**
+ * Lists snapshots.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listSnapshots(SnapshotListOption... options);
+
+ /**
+ * Deletes the requested snapshot. Keep in mind that deleting a single snapshot might not
+ * necessarily delete all the data for that snapshot. If any data for the snapshot that is marked
+ * for deletion is needed for subsequent snapshots, the data will be moved to the next snapshot.
+ *
+ * @return a global operation if the request was issued correctly, {@code null} if the snapshot
+ * was not found
+ * @throws ComputeException upon failure
+ * @see
+ * Deleting a snapshot
+ */
+ Operation deleteSnapshot(SnapshotId snapshot, OperationOption... options);
+
+ /**
+ * Deletes the requested snapshot. Keep in mind that deleting a single snapshot might not
+ * necessarily delete all the data for that snapshot. If any data on the snapshot that is marked
+ * for deletion is needed for subsequent snapshots, the data will be moved to the next snapshot.
+ *
+ * @return a global operation if the request was issued correctly, {@code null} if the snapshot
+ * was not found
+ * @throws ComputeException upon failure
+ * @see
+ * Deleting a snapshot
+ */
+ Operation deleteSnapshot(String snapshot, OperationOption... options);
+
+ /**
+ * Creates a new image.
+ *
+ * @return a global operation for image's creation
+ * @throws ComputeException upon failure
+ */
+ Operation create(ImageInfo image, OperationOption... options);
+
+ /**
+ * Returns the requested image or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Image getImage(ImageId imageId, ImageOption... options);
+
+ /**
+ * Lists images in the provided project that are available to the current user. This method can be
+ * used to list publicly-available images by providing the respective image project. Examples of
+ * image projects are: {@code centos-cloud}, {@code coreos-cloud}, {@code debian-cloud},
+ * {@code opensuse-cloud}, {@code rhel-cloud}, {@code suse-cloud}, {@code ubuntu-os-cloud} and
+ * {@code windows-cloud}. Attempting to delete or deprecate a publicly-available image will fail.
+ *
+ * @throws ComputeException upon failure
+ * @see Operating Systems
+ */
+ Page listImages(String project, ImageListOption... options);
+
+ /**
+ * Lists images in the current project.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listImages(ImageListOption... options);
+
+ /**
+ * Deletes the requested image.
+ *
+ * @return a global operation if the delete request was issued correctly, {@code null} if the
+ * image was not found
+ * @throws ComputeException upon failure or if {@code image} is a publicly-available image
+ */
+ Operation deleteImage(ImageId image, OperationOption... options);
+
+ /**
+ * Deprecates the requested image.
+ *
+ * @return a global operation if the deprecation request was issued correctly, {@code null} if the
+ * image was not found
+ * @throws ComputeException upon failure or if {@code image} is a publicly-available image
+ */
+ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus,
+ OperationOption... options);
+
+ /**
+ * Returns the requested disk or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Disk getDisk(DiskId diskId, DiskOption... options);
+
+ /**
+ * Creates a new disk.
+ *
+ * @return a zone operation for disk's creation
+ * @throws ComputeException upon failure
+ */
+ Operation create(DiskInfo disk, OperationOption... options);
+
+ /**
+ * Lists disks for the provided zone.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listDisks(String zone, DiskListOption... options);
+
+ /**
+ * Lists disks for all zones.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listDisks(DiskAggregatedListOption... options);
+
+ /**
+ * Deletes the requested disk.
+ *
+ * @return a zone operation if the request was issued correctly, {@code null} if the disk was not
+ * found
+ * @throws ComputeException upon failure
+ */
+ Operation deleteDisk(DiskId disk, OperationOption... options);
+
+ /**
+ * Resizes the disk to the requested size. The new size must be larger than the previous one.
+ *
+ * @return a zone operation if the request was issued correctly, {@code null} if the disk was not
+ * found
+ * @throws ComputeException upon failure or if the new disk size is smaller than the previous one
+ */
+ Operation resize(DiskId disk, long sizeGb, OperationOption... options);
+
+ /*
+ * Creates a new subnetwork.
+ *
+ * @return a region operation for subnetwork's creation
+ * @throws ComputeException upon failure
+ */
+ Operation create(SubnetworkInfo subnetwork, OperationOption... options);
+
+ /**
+ * Returns the requested subnetwork or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Subnetwork getSubnetwork(SubnetworkId subnetworkId, SubnetworkOption... options);
+
+ /**
+ * Lists subnetworks for the provided region.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listSubnetworks(String region, SubnetworkListOption... options);
+
+ /**
+ * Lists subnetworks for all regions.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listSubnetworks(SubnetworkAggregatedListOption... options);
+
+ /**
+ * Deletes the requested subnetwork. Any attempt to delete an automatically created subnetwork
+ * will fail.
+ *
+ * @return a region operation if the delete request was issued correctly, {@code null} if the
+ * subnetwork was not found
+ * @throws ComputeException upon failure
+ */
+ Operation deleteSubnetwork(SubnetworkId subnetwork, OperationOption... options);
+
+ /**
+ * Creates a new network.
+ *
+ * @return a global operation for network's creation
+ * @throws ComputeException upon failure
+ */
+ Operation create(NetworkInfo network, OperationOption... options);
+
+ /**
+ * Returns the requested network or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Network getNetwork(String network, NetworkOption... options);
+
+ /**
+ * Lists networks.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listNetworks(NetworkListOption... options);
+
+ /**
+ * Deletes the requested network.
+ *
+ * @return a global operation if the delete request was issued correctly, {@code null} if the
+ * network was not found
+ * @throws ComputeException upon failure
+ */
+ Operation deleteNetwork(String network, OperationOption... options);
+
+ /**
+ * Deletes the requested network.
+ *
+ * @return a global operation if the delete request was issued correctly, {@code null} if the
+ * network was not found
+ * @throws ComputeException upon failure
+ */
+ Operation deleteNetwork(NetworkId network, OperationOption... options);
+
+ /**
+ * Creates a new instance.
+ *
+ * @return a zone operation for instance's creation
+ * @throws ComputeException upon failure
+ */
+ Operation create(InstanceInfo instance, OperationOption... options);
+
+ /**
+ * Returns the requested instance or {@code null} if not found.
+ *
+ * @throws ComputeException upon failure
+ */
+ Instance getInstance(InstanceId instance, InstanceOption... options);
+
+ /**
+ * Lists instances for the provided zone.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listInstances(String zone, InstanceListOption... options);
+
+ /**
+ * Lists instances for all zones.
+ *
+ * @throws ComputeException upon failure
+ */
+ Page listInstances(InstanceAggregatedListOption... options);
+
+ /**
+ * Deletes the requested instance.
+ *
+ * @return a zone operation if the delete request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation deleteInstance(InstanceId instance, OperationOption... options);
+
+ /**
+ * Adds an access configuration to an instance's network interface.
+ *
+ * @return a zone operation if the add request was issued correctly, {@code null} if the instance
+ * was not found
+ * @throws ComputeException upon failure
+ */
+ Operation addAccessConfig(InstanceId instance, String networkInterface, AccessConfig accessConfig,
+ OperationOption... options);
+
+ /**
+ * Attaches a persistent disk to an instance given its configuration.
+ *
+ * @return a zone operation if the attach request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation attachDisk(InstanceId instance, PersistentDiskConfiguration configuration,
+ OperationOption... options);
+
+ /**
+ * Attaches a persistent disk to an instance given the device name and its configuration.
+ *
+ * @return a zone operation if the attach request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation attachDisk(InstanceId instance, String deviceName,
+ PersistentDiskConfiguration configuration, OperationOption... options);
+
+ /**
+ * Attaches a persistent disk to an instance given the device name, its configuration and the
+ * device index.
+ *
+ * @return a zone operation if the attach request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation attachDisk(InstanceId instance, String deviceName,
+ PersistentDiskConfiguration configuration, int index, OperationOption... options);
+
+ /**
+ * Deletes an access configuration from an instance's network interface.
+ *
+ * @return a zone operation if the delete request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation deleteAccessConfig(InstanceId instance, String networkInterface, String accessConfig,
+ OperationOption... options);
+
+ /**
+ * Detaches a disk from an instance.
+ *
+ * @return a zone operation if the detach request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation detachDisk(InstanceId instance, String deviceName, OperationOption... options);
+
+ /**
+ * Returns the serial port output for the provided instance and port number. {@code port} must be
+ * between 1 and 4 (inclusive).
+ *
+ * @return the serial port output or {@code null} if the instance was not found
+ * @throws ComputeException upon failure
+ */
+ String getSerialPortOutput(InstanceId instance, int port);
+
+ /**
+ * Returns the default serial port output for the provided instance. Default serial port
+ * corresponds to port number 1.
+ *
+ * @return the serial port output or {@code null} if the instance was not found
+ * @throws ComputeException upon failure
+ */
+ String getSerialPortOutput(InstanceId instance);
+
+ /**
+ * Resets the provided instance.
+ *
+ * @return a zone operation if the reset request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation reset(InstanceId instance, OperationOption... options);
+
+ /**
+ * Sets the auto-delete flag for a disk attached to the provided instance.
+ *
+ * @return a zone operation if the flag setting request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation setDiskAutoDelete(InstanceId instance, String deviceName, boolean autoDelete,
+ OperationOption... options);
+
+ /**
+ * Sets the machine type for the provided instance. Instance must be in
+ * {@link InstanceInfo.Status#TERMINATED} state to be able to set its machine type.
+ *
+ * @return a zone operation if the set request was issued correctly, {@code null} if the instance
+ * was not found
+ * @throws ComputeException upon failure
+ */
+ Operation setMachineType(InstanceId instance, MachineTypeId machineType,
+ OperationOption... options);
+
+ /**
+ * Sets the metadata for the provided instance.
+ *
+ * @return a zone operation if the set request was issued correctly, {@code null} if the instance
+ * was not found
+ * @throws ComputeException upon failure
+ */
+ Operation setMetadata(InstanceId instance, Metadata metadata, OperationOption... options);
+
+ /**
+ * Sets the scheduling options for the provided instance.
+ *
+ * @return a zone operation if the set request was issued correctly, {@code null} if the instance
+ * was not found
+ * @throws ComputeException upon failure
+ */
+ Operation setSchedulingOptions(InstanceId instance, SchedulingOptions scheduling,
+ OperationOption... options);
+
+ /**
+ * Sets the tags for the provided instance.
+ *
+ * @return a zone operation if the set request was issued correctly, {@code null} if the instance
+ * was not found
+ * @throws ComputeException upon failure
+ */
+ Operation setTags(InstanceId instance, Tags tags, OperationOption... options);
+
+ /**
+ * Starts the provided instance.
+ *
+ * @return a zone operation if the start request was issued correctly, {@code null} if the
+ * instance was not found
+ * @throws ComputeException upon failure
+ */
+ Operation start(InstanceId instance, OperationOption... options);
+
+ /**
+ * Stops the provided instance.
+ *
+ * @return a zone operation if the stop request was issued correctly, {@code null} if the instance
+ * was not found
+ * @throws ComputeException upon failure
+ */
+ Operation stop(InstanceId instance, OperationOption... options);
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeException.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeException.java
new file mode 100644
index 000000000000..1a69457040d6
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.cloud.compute;
+
+import com.google.cloud.BaseServiceException;
+import com.google.cloud.RetryHelper.RetryHelperException;
+import com.google.cloud.RetryHelper.RetryInterruptedException;
+import com.google.common.collect.ImmutableSet;
+
+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;
+
+ ComputeException(int code, String message) {
+ super(code, message, null, true, null);
+ }
+
+ ComputeException(int code, String message, Throwable cause) {
+ super(code, message, null, true, cause);
+ }
+
+ 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(), ex.getCause());
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeFactory.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeFactory.java
new file mode 100644
index 000000000000..a4daac3f4d56
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/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.cloud.compute;
+
+import com.google.cloud.ServiceFactory;
+
+/**
+ * An interface for Compute factories.
+ */
+public interface ComputeFactory extends ServiceFactory {
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java
new file mode 100644
index 000000000000..c0846749d326
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java
@@ -0,0 +1,2051 @@
+/*
+ * 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.cloud.compute;
+
+import static com.google.cloud.RetryHelper.runWithRetries;
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.cloud.BaseService;
+import com.google.cloud.Page;
+import com.google.cloud.PageImpl;
+import com.google.cloud.PageImpl.NextPageFetcher;
+import com.google.cloud.RetryHelper;
+import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration;
+import com.google.cloud.compute.NetworkInterface.AccessConfig;
+import com.google.cloud.compute.spi.ComputeRpc;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+final class ComputeImpl extends BaseService implements Compute {
+
+ private static class GlobalOperationPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -2488912172182315364L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ GlobalOperationPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listGlobalOperations(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class DiskTypePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -5253916264932522976L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String zone;
+
+ DiskTypePageFetcher(String zone, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.zone = zone;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listDiskTypes(zone, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class AggregatedDiskTypePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -1664743503750307996L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ AggregatedDiskTypePageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listDiskTypes(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class MachineTypePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -5048133000517001933L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String zone;
+
+ MachineTypePageFetcher(String zone, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.zone = zone;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listMachineTypes(zone, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class AggregatedMachineTypePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 2919227789802660026L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ AggregatedMachineTypePageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listMachineTypes(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class RegionPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 4180147045485258863L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ RegionPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listRegions(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class ZonePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -3946202621600687597L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ ZonePageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listZones(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class RegionOperationPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 4111705358926164078L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String region;
+
+ RegionOperationPageFetcher(String region, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.region = region;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listRegionOperations(region, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class ZoneOperationPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -9012504536518197793L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String zone;
+
+ ZoneOperationPageFetcher(String zone, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.zone = zone;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listZoneOperations(zone, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class GlobalAddressPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -3832055341507574454L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ GlobalAddressPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listGlobalAddresses(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class RegionAddressPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 7080596594494397027L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String region;
+
+ RegionAddressPageFetcher(String region, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.region = region;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listRegionAddresses(region, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class AggregatedAddressPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -5798942282919494950L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ AggregatedAddressPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listAddresses(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class SnapshotPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 6205774609802216986L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ SnapshotPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listSnapshots(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class ImagePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 6403679803137922023L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String project;
+
+ ImagePageFetcher(String project, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.project = project;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listImages(project, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class DiskPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 4146589787872718476L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String zone;
+
+ DiskPageFetcher(String zone, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.zone = zone;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listDisks(zone, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class AggregatedDiskPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = -5240045334115926206L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ AggregatedDiskPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listDisks(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class SubnetworkPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 3674038457884412651L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String region;
+
+ SubnetworkPageFetcher(String region, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.region = region;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listSubnetworks(region, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class AggregatedSubnetworkPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 771343548833894551L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ AggregatedSubnetworkPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listSubnetworks(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class NetworkPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 5580210850353114531L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ NetworkPageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listNetworks(serviceOptions, requestOptions);
+ }
+ }
+
+ private static class InstancePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 7563769742657453865L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+ private final String zone;
+
+ InstancePageFetcher(String zone, ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ this.zone = zone;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listInstances(zone, serviceOptions, requestOptions);
+ }
+ }
+
+ private static class AggregatedInstancePageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 1863059389783095681L;
+ private final Map requestOptions;
+ private final ComputeOptions serviceOptions;
+
+ AggregatedInstancePageFetcher(ComputeOptions serviceOptions, String cursor,
+ Map optionMap) {
+ this.requestOptions =
+ PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
+ this.serviceOptions = serviceOptions;
+ }
+
+ @Override
+ public Page nextPage() {
+ return listInstances(serviceOptions, requestOptions);
+ }
+ }
+
+ private final ComputeRpc computeRpc;
+
+ ComputeImpl(ComputeOptions options) {
+ super(options);
+ computeRpc = options.rpc();
+ }
+
+ @Override
+ public DiskType getDiskType(final DiskTypeId diskTypeId, DiskTypeOption... options) {
+ final Map optionsMap = optionMap(options);
+ try {
+ com.google.api.services.compute.model.DiskType answer =
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.DiskType call() {
+ return computeRpc.getDiskType(diskTypeId.zone(), diskTypeId.type(), optionsMap);
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ return answer == null ? null : DiskType.fromPb(answer);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public DiskType getDiskType(String zone, String diskType, DiskTypeOption... options) {
+ return getDiskType(DiskTypeId.of(zone, diskType), options);
+ }
+
+ @Override
+ public Page listDiskTypes(String zone, DiskTypeListOption... options) {
+ return listDiskTypes(zone, options(), optionMap(options));
+ }
+
+ private static Page listDiskTypes(final String zone,
+ final ComputeOptions serviceOptions, final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listDiskTypes(zone, optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable diskTypes = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(),
+ new Function() {
+ @Override
+ public DiskType apply(com.google.api.services.compute.model.DiskType diskType) {
+ return DiskType.fromPb(diskType);
+ }
+ });
+ return new PageImpl<>(new DiskTypePageFetcher(zone, serviceOptions, cursor, optionsMap),
+ cursor, diskTypes);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listDiskTypes(DiskTypeAggregatedListOption... options) {
+ return listDiskTypes(options(), optionMap(options));
+ }
+
+ private static Page listDiskTypes(final ComputeOptions serviceOptions,
+ final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listDiskTypes(optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable diskTypes = Iterables.transform(result.y(),
+ new Function() {
+ @Override
+ public DiskType apply(com.google.api.services.compute.model.DiskType diskType) {
+ return DiskType.fromPb(diskType);
+ }
+ });
+ return new PageImpl<>(new AggregatedDiskTypePageFetcher(serviceOptions, cursor, optionsMap),
+ cursor, diskTypes);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public MachineType getMachineType(final MachineTypeId machineType, MachineTypeOption... options) {
+ final Map optionsMap = optionMap(options);
+ try {
+ com.google.api.services.compute.model.MachineType answer =
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.MachineType call() {
+ return computeRpc.getMachineType(machineType.zone(), machineType.type(), optionsMap);
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ return answer == null ? null : MachineType.fromPb(answer);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public MachineType getMachineType(String zone, String machineType, MachineTypeOption... options) {
+ return getMachineType(MachineTypeId.of(zone, machineType), options);
+ }
+
+ @Override
+ public Page listMachineTypes(String zone, MachineTypeListOption... options) {
+ return listMachineTypes(zone, options(), optionMap(options));
+ }
+
+ private static Page listMachineTypes(final String zone,
+ final ComputeOptions serviceOptions, final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listMachineTypes(zone, optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable machineTypes = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(),
+ new Function() {
+ @Override
+ public MachineType apply(
+ com.google.api.services.compute.model.MachineType machineType) {
+ return MachineType.fromPb(machineType);
+ }
+ });
+ return new PageImpl<>(new MachineTypePageFetcher(zone, serviceOptions, cursor, optionsMap),
+ cursor, machineTypes);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listMachineTypes(MachineTypeAggregatedListOption... options) {
+ return listMachineTypes(options(), optionMap(options));
+ }
+
+ private static Page listMachineTypes(final ComputeOptions serviceOptions,
+ final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listMachineTypes(optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable machineTypes = Iterables.transform(result.y(),
+ new Function() {
+ @Override
+ public MachineType apply(
+ com.google.api.services.compute.model.MachineType machineType) {
+ return MachineType.fromPb(machineType);
+ }
+ });
+ return new PageImpl<>(
+ new AggregatedMachineTypePageFetcher(serviceOptions, cursor, optionsMap), cursor,
+ machineTypes);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Region getRegion(final String region, RegionOption... options) {
+ final Map optionsMap = optionMap(options);
+ try {
+ com.google.api.services.compute.model.Region answer =
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.Region call() {
+ return computeRpc.getRegion(region, optionsMap);
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ return answer == null ? null : Region.fromPb(answer);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listRegions(RegionListOption... options) {
+ return listRegions(options(), optionMap(options));
+ }
+
+ private static Page listRegions(final ComputeOptions serviceOptions,
+ final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listRegions(optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable regions = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(),
+ new Function() {
+ @Override
+ public Region apply(com.google.api.services.compute.model.Region region) {
+ return Region.fromPb(region);
+ }
+ });
+ return new PageImpl<>(new RegionPageFetcher(serviceOptions, cursor, optionsMap), cursor,
+ regions);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Zone getZone(final String zone, ZoneOption... options) {
+ final Map optionsMap = optionMap(options);
+ try {
+ com.google.api.services.compute.model.Zone answer =
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.Zone call() {
+ return computeRpc.getZone(zone, optionsMap);
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ return answer == null ? null : Zone.fromPb(answer);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listZones(ZoneListOption... options) {
+ return listZones(options(), optionMap(options));
+ }
+
+ private static Page listZones(final ComputeOptions serviceOptions,
+ final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listZones(optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable zones = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(),
+ new Function() {
+ @Override
+ public Zone apply(com.google.api.services.compute.model.Zone zone) {
+ return Zone.fromPb(zone);
+ }
+ });
+ return new PageImpl<>(new ZonePageFetcher(serviceOptions, cursor, optionsMap), cursor, zones);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public License getLicense(String license, LicenseOption... options) {
+ return getLicense(LicenseId.of(license), options);
+ }
+
+ @Override
+ public License getLicense(LicenseId license, LicenseOption... options) {
+ final LicenseId completeId = license.setProjectId(options().projectId());
+ final Map optionsMap = optionMap(options);
+ try {
+ com.google.api.services.compute.model.License answer =
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.License call() {
+ return computeRpc.getLicense(completeId.project(), completeId.license(), optionsMap);
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ return answer == null ? null : License.fromPb(answer);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Operation getOperation(final OperationId operationId, OperationOption... options) {
+ final Map optionsMap = optionMap(options);
+ try {
+ com.google.api.services.compute.model.Operation answer =
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.Operation call() {
+ switch (operationId.type()) {
+ case REGION:
+ RegionOperationId regionOperationId = (RegionOperationId) operationId;
+ return computeRpc.getRegionOperation(regionOperationId.region(),
+ regionOperationId.operation(), optionsMap);
+ case ZONE:
+ ZoneOperationId zoneOperationId = (ZoneOperationId) operationId;
+ return computeRpc.getZoneOperation(zoneOperationId.zone(),
+ zoneOperationId.operation(), optionsMap);
+ case GLOBAL:
+ return computeRpc.getGlobalOperation(operationId.operation(), optionsMap);
+ default:
+ throw new IllegalArgumentException("Unexpected operation identity type");
+ }
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ return answer == null ? null : Operation.fromPb(this, answer);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ private static Function
+ operationFromPb(final ComputeOptions serviceOptions) {
+ return new Function() {
+ @Override
+ public Operation apply(com.google.api.services.compute.model.Operation operation) {
+ return Operation.fromPb(serviceOptions.service(), operation);
+ }
+ };
+ }
+
+ @Override
+ public Page listGlobalOperations(OperationListOption... options) {
+ return listGlobalOperations(options(), optionMap(options));
+ }
+
+ private static Page listGlobalOperations(final ComputeOptions serviceOptions,
+ final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listGlobalOperations(optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable operations = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(), operationFromPb(serviceOptions));
+ return new PageImpl<>(new GlobalOperationPageFetcher(serviceOptions, cursor, optionsMap),
+ cursor, operations);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listRegionOperations(String region, OperationListOption... options) {
+ return listRegionOperations(region, options(), optionMap(options));
+ }
+
+ private static Page listRegionOperations(final String region,
+ final ComputeOptions serviceOptions, final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listRegionOperations(region, optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable operations = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(), operationFromPb(serviceOptions));
+ return new PageImpl<>(new RegionOperationPageFetcher(region, serviceOptions, cursor,
+ optionsMap), cursor, operations);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listZoneOperations(String zone, OperationListOption... options) {
+ return listZoneOperations(zone, options(), optionMap(options));
+ }
+
+ private static Page listZoneOperations(final String zone,
+ final ComputeOptions serviceOptions, final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listZoneOperations(zone, optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable operations = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(), operationFromPb(serviceOptions));
+ return new PageImpl<>(new ZoneOperationPageFetcher(zone, serviceOptions, cursor, optionsMap),
+ cursor, operations);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public boolean deleteOperation(final OperationId operation) {
+ try {
+ return runWithRetries(new Callable() {
+ @Override
+ public Boolean call() {
+ switch (operation.type()) {
+ case REGION:
+ RegionOperationId regionOperationId = (RegionOperationId) operation;
+ return computeRpc.deleteRegionOperation(regionOperationId.region(),
+ regionOperationId.operation());
+ case ZONE:
+ ZoneOperationId zoneOperationId = (ZoneOperationId) operation;
+ return computeRpc.deleteZoneOperation(zoneOperationId.zone(),
+ zoneOperationId.operation());
+ case GLOBAL:
+ return computeRpc.deleteGlobalOperation(operation.operation());
+ default:
+ throw new IllegalArgumentException("Unexpected operation identity type");
+ }
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Address getAddress(final AddressId addressId, AddressOption... options) {
+ final Map optionsMap = optionMap(options);
+ try {
+ com.google.api.services.compute.model.Address answer =
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.Address call() {
+ switch (addressId.type()) {
+ case REGION:
+ RegionAddressId regionAddressId = (RegionAddressId) addressId;
+ return computeRpc.getRegionAddress(regionAddressId.region(),
+ regionAddressId.address(), optionsMap);
+ case GLOBAL:
+ return computeRpc.getGlobalAddress(addressId.address(), optionsMap);
+ default:
+ throw new IllegalArgumentException("Unexpected address identity type");
+ }
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER);
+ return answer == null ? null : Address.fromPb(this, answer);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Operation create(final AddressInfo address, OperationOption... options) {
+ final com.google.api.services.compute.model.Address addressPb =
+ address.setProjectId(options().projectId()).toPb();
+ final Map optionsMap = optionMap(options);
+ try {
+ return Operation.fromPb(this,
+ runWithRetries(new Callable() {
+ @Override
+ public com.google.api.services.compute.model.Operation call() {
+ switch (address.addressId().type()) {
+ case REGION:
+ RegionAddressId regionAddressId = address.addressId();
+ return computeRpc.createRegionAddress(regionAddressId.region(), addressPb,
+ optionsMap);
+ case GLOBAL:
+ return computeRpc.createGlobalAddress(addressPb, optionsMap);
+ default:
+ throw new IllegalArgumentException("Unexpected address identity type");
+ }
+ }
+ }, options().retryParams(), EXCEPTION_HANDLER));
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ private static Function addressFromPb(
+ final ComputeOptions serviceOptions) {
+ return new Function() {
+ @Override
+ public Address apply(com.google.api.services.compute.model.Address address) {
+ return Address.fromPb(serviceOptions.service(), address);
+ }
+ };
+ }
+
+ @Override
+ public Page listGlobalAddresses(AddressListOption... options) {
+ return listGlobalAddresses(options(), optionMap(options));
+ }
+
+ private static Page listGlobalAddresses(final ComputeOptions serviceOptions,
+ final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listGlobalAddresses(optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable operations = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(), addressFromPb(serviceOptions));
+ return new PageImpl<>(new GlobalAddressPageFetcher(serviceOptions, cursor, optionsMap),
+ cursor, operations);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listRegionAddresses(String region, AddressListOption... options) {
+ return listRegionAddresses(region, options(), optionMap(options));
+ }
+
+ private static Page listRegionAddresses(final String region,
+ final ComputeOptions serviceOptions, final Map optionsMap) {
+ try {
+ ComputeRpc.Tuple> result =
+ runWithRetries(new Callable>>() {
+ @Override
+ public ComputeRpc.Tuple> call() {
+ return serviceOptions.rpc().listRegionAddresses(region, optionsMap);
+ }
+ }, serviceOptions.retryParams(), EXCEPTION_HANDLER);
+ String cursor = result.x();
+ Iterable operations = Iterables.transform(
+ result.y() == null ? ImmutableList.of()
+ : result.y(), addressFromPb(serviceOptions));
+ return new PageImpl<>(new RegionAddressPageFetcher(region, serviceOptions, cursor,
+ optionsMap), cursor, operations);
+ } catch (RetryHelper.RetryHelperException e) {
+ throw ComputeException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page