optionMap = Maps.newEnumMap(ComputeRpc.Option.class);
+ for (Option option : options) {
+ Object prev = optionMap.put(option.rpcOption(), option.value());
+ checkArgument(prev == null, "Duplicate option %s", option);
+ }
+ return optionMap;
+ }
}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java
new file mode 100644
index 000000000000..ae100c9c9765
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gcloud.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.MoreObjects;
+import com.google.gcloud.spi.ComputeRpc;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Base class for Compute operation option.
+ */
+class Option implements Serializable {
+
+ private static final long serialVersionUID = 4116849309806774350L;
+
+ private final ComputeRpc.Option rpcOption;
+ private final Object value;
+
+ Option(ComputeRpc.Option rpcOption, Object value) {
+ this.rpcOption = checkNotNull(rpcOption);
+ this.value = value;
+ }
+
+ ComputeRpc.Option rpcOption() {
+ return rpcOption;
+ }
+
+ Object value() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Option)) {
+ return false;
+ }
+ Option other = (Option) obj;
+ return Objects.equals(rpcOption, other.rpcOption)
+ && Objects.equals(value, other.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(rpcOption, value);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("name", rpcOption.value())
+ .add("value", value)
+ .toString();
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java
new file mode 100644
index 000000000000..266b31cd7c93
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gcloud.compute.testing;
+
+import com.google.gcloud.AuthCredentials;
+import com.google.gcloud.RetryParams;
+import com.google.gcloud.compute.ComputeOptions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Utility to create a remote Compute configuration for testing. Compute options can be obtained
+ * via the {@link #options()} method. Returned options have custom
+ * {@link ComputeOptions#retryParams()}: {@link RetryParams#retryMaxAttempts()} is {@code 10},
+ * {@link RetryParams#retryMinAttempts()} is {@code 6}, {@link RetryParams#maxRetryDelayMillis()} is
+ * {@code 30000}, {@link RetryParams#totalRetryPeriodMillis()} is {@code 120000} and
+ * {@link RetryParams#initialRetryDelayMillis()} is {@code 250}.
+ * {@link ComputeOptions#connectTimeout()} and {@link ComputeOptions#readTimeout()} are both set to
+ * {@code 60000}.
+ */
+public class RemoteComputeHelper {
+
+ private static final Logger log = Logger.getLogger(RemoteComputeHelper.class.getName());
+ private final ComputeOptions options;
+
+ private RemoteComputeHelper(ComputeOptions options) {
+ this.options = options;
+ }
+
+ /**
+ * Returns a {@link ComputeOptions} object to be used for testing.
+ */
+ public ComputeOptions options() {
+ return options;
+ }
+
+ /**
+ * Creates a {@code RemoteComputeHelper} object for the given project id and JSON key input
+ * stream.
+ *
+ * @param projectId id of the project to be used for running the tests
+ * @param keyStream input stream for a JSON key
+ * @return A {@code RemoteComputeHelper} object for the provided options
+ * @throws ComputeHelperException if {@code keyStream} is not a valid JSON key stream
+ */
+ public static RemoteComputeHelper create(String projectId, InputStream keyStream)
+ throws ComputeHelperException {
+ try {
+ ComputeOptions computeOptions = ComputeOptions.builder()
+ .authCredentials(AuthCredentials.createForJson(keyStream))
+ .projectId(projectId)
+ .retryParams(retryParams())
+ .connectTimeout(60000)
+ .readTimeout(60000)
+ .build();
+ return new RemoteComputeHelper(computeOptions);
+ } catch (IOException ex) {
+ if (log.isLoggable(Level.WARNING)) {
+ log.log(Level.WARNING, ex.getMessage());
+ }
+ throw ComputeHelperException.translate(ex);
+ }
+ }
+
+ /**
+ * Creates a {@code RemoteComputeHelper} object using default project id and authentication
+ * credentials.
+ */
+ public static RemoteComputeHelper create() {
+ ComputeOptions computeOptions = ComputeOptions.builder()
+ .retryParams(retryParams())
+ .connectTimeout(60000)
+ .readTimeout(60000)
+ .build();
+ return new RemoteComputeHelper(computeOptions);
+ }
+
+ private static RetryParams retryParams() {
+ return RetryParams.builder()
+ .retryMaxAttempts(10)
+ .retryMinAttempts(6)
+ .maxRetryDelayMillis(30000)
+ .totalRetryPeriodMillis(120000)
+ .initialRetryDelayMillis(250)
+ .build();
+ }
+
+ public static class ComputeHelperException extends RuntimeException {
+
+ private static final long serialVersionUID = -5747977015007639912L;
+
+ public ComputeHelperException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public static ComputeHelperException translate(Exception ex) {
+ return new ComputeHelperException(ex.getMessage(), ex);
+ }
+ }
+}
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java
new file mode 100644
index 000000000000..86f1c2428cde
--- /dev/null
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * A testing helper for Google Compute Engine.
+ *
+ * A simple usage example:
+ *
+ *
Before the test:
+ *
{@code
+ * RemoteComputeHelper computeHelper = RemoteComputeHelper.create();
+ * Compute compute = computeHelper.options().service();
+ * }
+ *
+ * @see
+ * gcloud-java tools for testing
+ */
+package com.google.gcloud.compute.testing;
diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
index b7a59a9413c4..35524e0c116d 100644
--- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
+++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
@@ -16,5 +16,149 @@
package com.google.gcloud.spi;
+import com.google.api.services.compute.model.DiskType;
+import com.google.api.services.compute.model.License;
+import com.google.api.services.compute.model.MachineType;
+import com.google.api.services.compute.model.Region;
+import com.google.api.services.compute.model.Zone;
+import com.google.gcloud.compute.ComputeException;
+
+import java.util.Map;
+
public interface ComputeRpc {
+
+ // These options are part of the Google Compute Engine query parameters
+ enum Option {
+ FIELDS("fields"),
+ MAX_RESULTS("maxResults"),
+ PAGE_TOKEN("pageToken"),
+ FILTER("filter");
+
+ private final String value;
+
+ Option(String value) {
+ this.value = value;
+ }
+
+ public String value() {
+ return value;
+ }
+
+ @SuppressWarnings("unchecked")
+ T get(Map