From 9ba2701f9c9b54b9fe88ad2d73a5670796176880 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 23 May 2016 11:52:15 +0200 Subject: [PATCH] Add blocking waitFor method, remove whenDone and callback --- README.md | 50 ++---- .../java/com/google/cloud/bigquery/Job.java | 81 +++++----- .../google/cloud/bigquery/package-info.java | 15 +- .../com/google/cloud/bigquery/JobTest.java | 66 ++++---- .../cloud/bigquery/it/ITBigQueryTest.java | 41 ++--- gcloud-java-compute/README.md | 63 +++----- .../com/google/cloud/compute/Operation.java | 80 +++++----- .../google/cloud/compute/package-info.java | 34 ++-- .../google/cloud/compute/OperationTest.java | 63 +++++--- .../cloud/compute/it/ITComputeTest.java | 146 ++++++++---------- .../examples/bigquery/BigQueryExample.java | 25 ++- .../snippets/CreateTableAndLoadData.java | 20 +-- .../CreateAddressDiskAndInstance.java | 61 +++----- .../compute/snippets/CreateInstance.java | 22 +-- .../compute/snippets/CreateSnapshot.java | 22 +-- 15 files changed, 333 insertions(+), 456 deletions(-) diff --git a/README.md b/README.md index dd6c13556a1b..8466dc953aa3 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,6 @@ Complete source code can be found at ```java import com.google.cloud.bigquery.BigQuery; -import com.google.cloud.bigquery.BigQueryError; import com.google.cloud.bigquery.BigQueryOptions; import com.google.cloud.bigquery.Field; import com.google.cloud.bigquery.FormatOptions; @@ -156,8 +155,6 @@ import com.google.cloud.bigquery.Table; import com.google.cloud.bigquery.TableId; import com.google.cloud.bigquery.TableInfo; -import java.util.List; - BigQuery bigquery = BigQueryOptions.defaultInstance().service(); TableId tableId = TableId.of("dataset", "table"); Table table = bigquery.getTable(tableId); @@ -169,17 +166,12 @@ if (table == null) { } System.out.println("Loading data into table " + tableId); Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path"); -loadJob.whenDone(new Job.CompletionCallback() { - @Override - public void success(Job job) { - System.out.println("Job succeeded"); - } - - @Override - public void error(BigQueryError error, List executionErrors) { - System.out.println("Job completed with errors"); - } -}); +loadJob = loadJob.waitFor(); +if (loadJob.status().error() != null) { + System.out.println("Job completed with errors"); +} else { + System.out.println("Job succeeded"); +} ``` Google Cloud Compute (Alpha) @@ -202,31 +194,19 @@ 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.OperationError; -import com.google.cloud.compute.Operation.OperationWarning; import com.google.cloud.compute.Snapshot; -import java.util.List; - final 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) { final String snapshotName = "disk-name-snapshot"; Operation operation = disk.createSnapshot(snapshotName); - operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - // use snapshot - Snapshot snapshot = compute.getSnapshot(snapshotName); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Snaphsot creation failed"); - } - }); + operation = operation.waitFor(); + if (operation.errors() == null) { + // use snapshot + Snapshot snapshot = compute.getSnapshot(snapshotName); + } } ``` The second snippet shows how to create a virtual machine instance. Complete source code can be found @@ -242,10 +222,6 @@ 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.Operation.OperationError; -import com.google.cloud.compute.Operation.OperationWarning; - -import java.util.List; Compute compute = ComputeOptions.defaultInstance().service(); ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); @@ -256,9 +232,7 @@ 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); -} +operation = operation.waitFor(); if (operation.errors() == null) { // use instance Instance instance = compute.getInstance(instanceId); diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java index caea0ee38390..0089bff21dd7 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java @@ -20,8 +20,8 @@ import java.io.IOException; import java.io.ObjectInputStream; -import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; /** * A Google BigQuery Job. @@ -38,24 +38,6 @@ public class Job extends JobInfo { private final BigQueryOptions options; private transient BigQuery bigquery; - /** - * A callback for job completion. - */ - public interface CompletionCallback { - /** - * The method called when the job completes successfully. - */ - void success(Job job); - - /** - * The method called when the job completes with errors. {@code error} is the final error that - * caused the job to fail (see {@link JobStatus#error()}). {@code executionErrors} are all the - * errors (possibly not fatal) encountered by the job during its execution (see - * {@link JobStatus#executionErrors()}). - */ - void error(BigQueryError error, List executionErrors); - } - /** * A builder for {@code Job} objects. */ @@ -163,40 +145,51 @@ public boolean isDone() { } /** - * Waits until this job completes its execution, either failing or succeeding. If the job does not - * exist, this method returns without executing any method of the provided callback. If the job - * completed successfully the {@link CompletionCallback#success(Job)} method is called. If the job - * completed with errors the {@link CompletionCallback#error(BigQueryError, List)} method is - * called. + * Blocks until this job completes its execution, either failing or succeeding. The job status is + * checked every 500 milliseconds. This method returns current job's latest information. If the + * job no longer exists, this method returns {@code null}. *
 {@code
-   * job.whenDone(new CompletionCallback() {
-   *   void success(Job job) {
-   *     // completed successfully
-   *   }
+   * Job completedJob = job.waitFor();
+   * if (completedJob == null) {
+   *   // job no longer exists
+   * } else if (completedJob.status().error() != null) {
+   *   // job failed, handle error
+   * } else {
+   *   // job completed successfully
+   * }}
* - * void error(BigQueryError error, List executionErrors) { - * // handle error - * } - * });} + * @throws BigQueryException upon failure + * @throws InterruptedException if the current thread gets interrupted while waiting for the job + * to complete + */ + public Job waitFor() throws InterruptedException { + return waitFor(500, TimeUnit.MILLISECONDS); + } + + /** + * Blocks until this job completes its execution, either failing or succeeding. The + * {@code checkEvery} and {@code unit} parameters determine how often the job's status is checked. + * This method returns current job's latest information. If the job no longer exists, this method + * returns {@code null}. + *
 {@code
+   * Job completedJob = job.waitFor(1, TimeUnit.SECONDS);
+   * if (completedJob == null) {
+   *   // job no longer exists
+   * } else if (completedJob.status().error() != null) {
+   *   // job failed, handle error
+   * } else {
+   *   // job completed successfully
+   * }}
* * @throws BigQueryException upon failure * @throws InterruptedException if the current thread gets interrupted while waiting for the job * to complete */ - public void whenDone(CompletionCallback callback) throws InterruptedException { + public Job waitFor(int checkEvery, TimeUnit unit) throws InterruptedException { while (!isDone()) { - Thread.sleep(500L); - } - Job updatedJob = reload(); - if (updatedJob == null) { - return; - } - BigQueryError error = updatedJob.status().error(); - if (error != null) { - callback.error(error, updatedJob.status().executionErrors()); - } else { - callback.success(updatedJob); + unit.sleep(checkEvery); } + return reload(); } /** diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java index 19e1d96fedef..3b4d392d26dc 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java @@ -33,15 +33,12 @@ * } * System.out.println("Loading data into table " + tableId); * Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path"); - * loadJob.whenDone(new Job.CompletionCallback() { - * public void success(Job job) { - * System.out.println("Job succeeded"); - * } - * - * public void error(BigQueryError error, List executionErrors) { - * System.out.println("Job completed with errors"); - * } - * });} + * loadJob = loadJob.waitFor(); + * if (loadJob.status().error() != null) { + * System.out.println("Job completed with errors"); + * } else { + * System.out.println("Job succeeded"); + * }} * * @see Google Cloud BigQuery */ diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java index 11896baded43..26178054d304 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java @@ -28,13 +28,12 @@ import static org.junit.Assert.assertTrue; import com.google.cloud.bigquery.JobStatistics.CopyStatistics; -import com.google.common.collect.ImmutableList; import org.easymock.EasyMock; import org.junit.After; import org.junit.Test; -import java.util.List; +import java.util.concurrent.TimeUnit; public class JobTest { @@ -182,60 +181,71 @@ public void testIsDone_NotExists() throws Exception { } @Test - public void testWhenDone_Success() throws InterruptedException { + public void testWaitFor() throws InterruptedException { initializeExpectedJob(2); - Job.CompletionCallback callback = EasyMock.mock(Job.CompletionCallback.class); BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; JobStatus status = createStrictMock(JobStatus.class); expect(status.state()).andReturn(JobStatus.State.DONE); - expect(status.error()).andReturn(null); expect(bigquery.options()).andReturn(mockOptions); Job completedJob = expectedJob.toBuilder().status(status).build(); expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(completedJob); expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(completedJob); - callback.success(completedJob); - EasyMock.expectLastCall(); - replay(status, bigquery, callback); + replay(status, bigquery); initializeJob(); - job.whenDone(callback); - verify(status, callback); + assertSame(completedJob, job.waitFor()); + verify(status); } @Test - public void testWhenDone_Error() throws InterruptedException { - initializeExpectedJob(2); - Job.CompletionCallback callback = EasyMock.mock(Job.CompletionCallback.class); + public void testWaitFor_Null() throws InterruptedException { + initializeExpectedJob(1); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + expect(bigquery.options()).andReturn(mockOptions); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(null); + replay(bigquery); + initializeJob(); + assertNull(job.waitFor()); + } + + @Test + public void testWaitForWithTimeUnit() throws InterruptedException { + initializeExpectedJob(3); BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; - BigQueryError error = new BigQueryError("reason", "location", "message"); - List executionErrors = ImmutableList.of(error); + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); + EasyMock.expectLastCall(); JobStatus status = createStrictMock(JobStatus.class); + expect(status.state()).andReturn(JobStatus.State.RUNNING); expect(status.state()).andReturn(JobStatus.State.DONE); - expect(status.error()).andReturn(error); - expect(status.executionErrors()).andReturn(executionErrors); expect(bigquery.options()).andReturn(mockOptions); + Job runningJob = expectedJob.toBuilder().status(status).build(); Job completedJob = expectedJob.toBuilder().status(status).build(); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(runningJob); expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(completedJob); expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(completedJob); - callback.error(error, executionErrors); - EasyMock.expectLastCall(); - replay(status, bigquery, callback); + replay(status, bigquery, timeUnit); initializeJob(); - job.whenDone(callback); - verify(status, callback); + assertSame(completedJob, job.waitFor(42, timeUnit)); + verify(status, timeUnit); } @Test - public void testWhenDone_Null() throws InterruptedException { - initializeExpectedJob(1); - Job.CompletionCallback callback = EasyMock.mock(Job.CompletionCallback.class); + public void testWaitForWithTimeUnit_Null() throws InterruptedException { + initializeExpectedJob(2); BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); + EasyMock.expectLastCall(); expect(bigquery.options()).andReturn(mockOptions); + Job runningJob = expectedJob.toBuilder().status(new JobStatus(JobStatus.State.RUNNING)).build(); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(runningJob); expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null); expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(null); - replay(bigquery, callback); + replay(bigquery, timeUnit); initializeJob(); - job.whenDone(callback); - verify(callback); + assertNull(job.waitFor(42, timeUnit)); + verify(bigquery, timeUnit); } @Test diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 444b25add682..eb3b8c9c5597 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -188,11 +188,8 @@ public static void beforeClass() throws InterruptedException { .schema(TABLE_SCHEMA) .build(); Job job = bigquery.create(JobInfo.of(configuration)); - Job.CompletionCallback callback = EasyMock.createStrictMock(Job.CompletionCallback.class); - callback.success(EasyMock.anyObject()); - EasyMock.replay(callback); - job.whenDone(callback); - EasyMock.verify(callback); + job = job.waitFor(); + assertNull(job.status().error()); } @AfterClass @@ -800,11 +797,8 @@ public void testCopyJob() throws InterruptedException { TableId destinationTable = TableId.of(DATASET, destinationTableName); CopyJobConfiguration configuration = CopyJobConfiguration.of(destinationTable, sourceTable); Job remoteJob = bigquery.create(JobInfo.of(configuration)); - Job.CompletionCallback callback = EasyMock.createStrictMock(Job.CompletionCallback.class); - callback.success(EasyMock.anyObject()); - EasyMock.replay(callback); - remoteJob.whenDone(callback); - EasyMock.verify(callback); + remoteJob = remoteJob.waitFor(); + assertNull(remoteJob.status().error()); Table remoteTable = bigquery.getTable(DATASET, destinationTableName); assertNotNull(remoteTable); assertEquals(destinationTable.dataset(), remoteTable.tableId().dataset()); @@ -827,11 +821,8 @@ public void testQueryJob() throws InterruptedException { .destinationTable(destinationTable) .build(); Job remoteJob = bigquery.create(JobInfo.of(configuration)); - Job.CompletionCallback callback = EasyMock.createStrictMock(Job.CompletionCallback.class); - callback.success(EasyMock.anyObject()); - EasyMock.replay(callback); - remoteJob.whenDone(callback); - EasyMock.reset(callback); + remoteJob = remoteJob.waitFor(); + assertNull(remoteJob.status().error()); QueryResponse response = bigquery.getQueryResults(remoteJob.jobId()); while (!response.jobCompleted()) { @@ -869,21 +860,16 @@ public void testExtractJob() throws InterruptedException { .schema(SIMPLE_SCHEMA) .build(); Job remoteLoadJob = bigquery.create(JobInfo.of(configuration)); - Job.CompletionCallback callback = EasyMock.createStrictMock(Job.CompletionCallback.class); - callback.success(EasyMock.anyObject()); - EasyMock.replay(callback); - remoteLoadJob.whenDone(callback); - EasyMock.reset(callback); + remoteLoadJob = remoteLoadJob.waitFor(); + assertNull(remoteLoadJob.status().error()); ExtractJobConfiguration extractConfiguration = ExtractJobConfiguration.builder(destinationTable, "gs://" + BUCKET + "/" + EXTRACT_FILE) .printHeader(false) .build(); Job remoteExtractJob = bigquery.create(JobInfo.of(extractConfiguration)); - callback.success(EasyMock.anyObject()); - EasyMock.replay(callback); - remoteExtractJob.whenDone(callback); - EasyMock.verify(callback); + remoteExtractJob = remoteExtractJob.waitFor(); + assertNull(remoteExtractJob.status().error()); assertEquals(CSV_CONTENT, new String(storage.readAllBytes(BUCKET, EXTRACT_FILE), StandardCharsets.UTF_8)); assertTrue(bigquery.delete(DATASET, tableName)); @@ -900,11 +886,8 @@ public void testCancelJob() throws InterruptedException { .build(); Job remoteJob = bigquery.create(JobInfo.of(configuration)); assertTrue(remoteJob.cancel()); - Job.CompletionCallback callback = EasyMock.createStrictMock(Job.CompletionCallback.class); - callback.success(EasyMock.anyObject()); - EasyMock.replay(callback); - remoteJob.whenDone(callback); - EasyMock.verify(callback); + remoteJob = remoteJob.waitFor(); + assertNull(remoteJob.status().error()); } @Test diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index 49e692da84c2..81d48759221d 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -104,11 +104,7 @@ 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.Operation.OperationError; -import com.google.cloud.compute.Operation.OperationWarning; import com.google.cloud.compute.RegionAddressId; - -import java.util.List; ``` Then add the following code to create an address. Most Compute Engine calls return an `Operation` @@ -119,18 +115,13 @@ succeeded: final RegionAddressId addressId = RegionAddressId.of("us-central1", "test-address"); Operation operation = compute.create(AddressInfo.of(addressId)); // Wait for operation to complete -operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - System.out.println("Address " + addressId + " was successfully created"); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Address creation failed"); - } -}); +operation = operation.waitFor(); +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 @@ -157,18 +148,14 @@ 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); -operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - System.out.println("Disk " + diskId + " was successfully created"); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Disk creation failed"); - } -}); +// Wait for operation to complete +operation = operation.waitFor(); +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 @@ -207,18 +194,14 @@ MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1") InstanceInfo instance = InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface); Operation operation = compute.create(instance); -operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - System.out.println("Instance " + instanceId + " was successfully created"); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Instance creation failed"); - } -}); +// Wait for operation to complete +operation = operation.waitFor(); +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 diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java index 9ec6ccc54278..cf8afb04cfbb 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java @@ -36,6 +36,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.TimeUnit; /** * Google Compute Engine operations. Operation identity can be obtained via {@link #operationId()}. @@ -292,24 +293,6 @@ public int hashCode() { } } - /** - * A callback for operation completion. - */ - public interface CompletionCallback { - /** - * The method called when the operation completes successfully. - */ - void success(Operation operation); - - /** - * The method called when the operation completes with errors. {@code errors} contains all - * errors encountered while processing this operation (see {@link Operation#errors()}). - * {@code warnings} contains all warnings encountered while processing this operation (see - * {@link Operation#warnings()}). - */ - void error(List errors, List warnings); - } - static final class Builder { private Compute compute; @@ -677,40 +660,51 @@ public boolean isDone() { } /** - * Waits until this operation completes its execution, either failing or succeeding. If the - * operation does not exist, this method returns without executing any method of the provided - * callback. If the operation completed successfully the - * {@link CompletionCallback#success(Operation)} method is called. If the operation completed with - * errors the {@link CompletionCallback#error(List, List)} method is called. + * Blocks until this operation completes its execution, either failing or succeeding. The + * operation status is checked every 500 milliseconds. This method returns current operation's + * latest information. If the operation no longer exists, this method returns {@code null}. *
 {@code
-   * operation.whenDone(new CompletionCallback() {
-   *   void success(Operation operation) {
-   *     // completed successfully
-   *   }
+   * Operation completedOperation = operation.waitFor();
+   * if (completedOperation == null) {
+   *   // operation no longer exists
+   * } else if (completedOperation.errors() != null) {
+   *   // operation failed, handle error
+   * } else {
+   *   // operation completed successfully
+   * }}
* - * void error(List errors, List warnings) { - * // handle error - * } - * });} + * @throws ComputeException upon failure + * @throws InterruptedException if the current thread gets interrupted while waiting for the + * operation to complete + */ + public Operation waitFor() throws InterruptedException { + return waitFor(500, TimeUnit.MILLISECONDS); + } + + /** + * Blocks until this operation completes its execution, either failing or succeeding. The + * {@code checkEvery} and {@code unit} parameters determine how often the operation status is + * checked. This method returns current operation's latest information. If the operation no longer + * exists, this method returns {@code null}. + *
 {@code
+   * Operation completedOperation = operation.waitFor(1, TimeUnit.SECONDS);
+   * if (completedOperation == null) {
+   *   // operation no longer exists
+   * } else if (completedOperation.errors() != null) {
+   *   // operation failed, handle error
+   * } else {
+   *   // operation completed successfully
+   * }}
* * @throws ComputeException upon failure * @throws InterruptedException if the current thread gets interrupted while waiting for the * operation to complete */ - public void whenDone(CompletionCallback callback) throws InterruptedException { + public Operation waitFor(int checkEvery, TimeUnit unit) throws InterruptedException { while (!isDone()) { - Thread.sleep(500L); - } - Operation updatedOperation = reload(); - if (updatedOperation == null) { - return; - } - List errors = updatedOperation.errors(); - if (errors != null) { - callback.error(errors, updatedOperation.warnings()); - } else { - callback.success(updatedOperation); + unit.sleep(checkEvery); } + return reload(); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java index 3b1c703fa9b0..da0a43ac43cf 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java @@ -28,17 +28,11 @@ * if (disk != null) { * final String snapshotName = "disk-name-snapshot"; * Operation operation = disk.createSnapshot(snapshotName); - * operation.whenDone(new Operation.CompletionCallback() { - * public void success(Operation operation) { - * // use snapshot - * Snapshot snapshot = compute.getSnapshot(snapshotName); - * } - * - * public void error(List errors, List warnings) { - * // inspect errors - * throw new RuntimeException("Snaphsot creation failed"); - * } - * }); + * operation = operation.waitFor(); + * if (operation.errors() == null) { + * // use snapshot + * Snapshot snapshot = compute.getSnapshot(snapshotName); + * } * }} *

This second example shows how to create a virtual machine instance. Complete source code can * be found at @@ -53,18 +47,12 @@ * final 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)); - * operation.whenDone(new Operation.CompletionCallback() { - * public void success(Operation operation) { - * // use instance - * Instance instance = compute.getInstance(instanceId); - * } - * - * public void error(List errors, List warnings) { - * // inspect errors - * throw new RuntimeException("Instance creation failed"); - * } - * });} + * compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); + * operation = operation.waitFor(); + * if (operation.errors() == null) { + * // use instance + * Instance instance = compute.getInstance(instanceId); + * }} * * @see Google Cloud Compute */ diff --git a/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java index b07411e1607e..63a0fc511d26 100644 --- a/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java @@ -38,6 +38,7 @@ import org.junit.Test; import java.util.List; +import java.util.concurrent.TimeUnit; public class OperationTest { @@ -356,9 +357,8 @@ public void testIsDone_NotExists() throws Exception { } @Test - public void testWhenDone_Success() throws InterruptedException { + public void testWaitFor() throws InterruptedException { initializeExpectedOperation(4); - Operation.CompletionCallback callback = EasyMock.mock(Operation.CompletionCallback.class); Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; Operation successOperation = @@ -366,44 +366,65 @@ public void testWhenDone_Success() throws InterruptedException { expect(compute.options()).andReturn(mockOptions); expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(successOperation); expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(successOperation); - callback.success(successOperation); - EasyMock.expectLastCall(); - replay(compute, callback); + replay(compute); initializeOperation(); - operation.whenDone(callback); - verify(callback); + assertSame(successOperation, operation.waitFor()); } @Test - public void testWhenDone_Error() throws InterruptedException { + public void testWaitFor_Null() throws InterruptedException { initializeExpectedOperation(3); - Operation.CompletionCallback callback = EasyMock.mock(Operation.CompletionCallback.class); Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; expect(compute.options()).andReturn(mockOptions); - expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); - expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(globalOperation); - callback.error(ERRORS, WARNINGS); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(null); + replay(compute); + initializeOperation(); + assertNull(operation.waitFor()); + } + + @Test + public void testWaitForWithTimeUnit() throws InterruptedException { + initializeExpectedOperation(5); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); EasyMock.expectLastCall(); - replay(compute, callback); + Operation runningOperation = Operation.fromPb(serviceMockReturnsOptions, + globalOperation.toPb().setError(null).setStatus("RUNNING")); + Operation completedOperation = + Operation.fromPb(serviceMockReturnsOptions, globalOperation.toPb().setError(null)); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(runningOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)) + .andReturn(completedOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(completedOperation); + replay(compute, timeUnit); initializeOperation(); - operation.whenDone(callback); - verify(callback); + assertSame(completedOperation, operation.waitFor(42, timeUnit)); + verify(timeUnit); } @Test - public void testWhenDone_Null() throws InterruptedException { - initializeExpectedOperation(3); - Operation.CompletionCallback callback = EasyMock.mock(Operation.CompletionCallback.class); + public void testWaitForWithTimeUnit_Null() throws InterruptedException { + initializeExpectedOperation(4); Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); + EasyMock.expectLastCall(); + Operation runningOperation = Operation.fromPb(serviceMockReturnsOptions, + globalOperation.toPb().setError(null).setStatus("RUNNING")); expect(compute.options()).andReturn(mockOptions); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(runningOperation); expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(null); - replay(compute, callback); + replay(compute, timeUnit); initializeOperation(); - operation.whenDone(callback); - verify(callback); + assertNull(operation.waitFor(42, timeUnit)); + verify(compute, timeUnit); } @Test diff --git a/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java index e67efd7e5ae2..ba9b58d775e1 100644 --- a/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java @@ -56,9 +56,6 @@ import com.google.cloud.compute.NetworkInfo; import com.google.cloud.compute.NetworkInterface; import com.google.cloud.compute.Operation; -import com.google.cloud.compute.Operation.CompletionCallback; -import com.google.cloud.compute.Operation.OperationError; -import com.google.cloud.compute.Operation.OperationWarning; import com.google.cloud.compute.Region; import com.google.cloud.compute.RegionAddressId; import com.google.cloud.compute.RegionOperationId; @@ -103,17 +100,6 @@ public class ITComputeTest { private static final ImageId IMAGE_ID = ImageId.of("debian-cloud", "debian-8-jessie-v20160219"); private static final String IMAGE_PROJECT = "debian-cloud"; - private static final CompletionCallback EMPTY_CALLBACK = new CompletionCallback() { - @Override - public void success(Operation operation) { - // do nothing - } - - @Override - public void error(List errors, List warnings) { - // do noting - } - }; private static Compute compute; @Rule @@ -700,7 +686,7 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { AddressId addressId = RegionAddressId.of(REGION, name); AddressInfo addressInfo = AddressInfo.of(addressId); Operation operation = compute.create(addressInfo); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); // test get Address remoteAddress = compute.getAddress(addressId); assertNotNull(remoteAddress); @@ -721,7 +707,7 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { assertNull(remoteAddress.creationTimestamp()); assertNull(remoteAddress.generatedId()); operation = remoteAddress.delete(); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); assertNull(compute.getAddress(addressId)); } @@ -733,8 +719,8 @@ public void testListRegionAddresses() throws InterruptedException { AddressId secondAddressId = RegionAddressId.of(REGION, addressNames[1]); Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); Set addressSet = ImmutableSet.copyOf(addressNames); // test list Compute.AddressFilter filter = @@ -785,8 +771,8 @@ public void testAggregatedListAddresses() throws InterruptedException { AddressId secondAddressId = GlobalAddressId.of(REGION, addressNames[1]); Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); Set addressSet = ImmutableSet.copyOf(addressNames); Compute.AddressFilter filter = Compute.AddressFilter.equals(Compute.AddressField.NAME, prefix + "\\d"); @@ -814,7 +800,7 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { AddressId addressId = GlobalAddressId.of(name); AddressInfo addressInfo = AddressInfo.of(addressId); Operation operation = compute.create(addressInfo); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); // test get Address remoteAddress = compute.getAddress(addressId); assertNotNull(remoteAddress); @@ -833,7 +819,7 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { assertNull(remoteAddress.creationTimestamp()); assertNull(remoteAddress.generatedId()); operation = remoteAddress.delete(); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); assertNull(compute.getAddress(addressId)); } @@ -845,8 +831,8 @@ public void testListGlobalAddresses() throws InterruptedException { AddressId secondAddressId = GlobalAddressId.of(addressNames[1]); Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); Set addressSet = ImmutableSet.copyOf(addressNames); // test list Compute.AddressFilter filter = @@ -894,7 +880,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti DiskInfo diskInfo = DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); Operation operation = compute.create(diskInfo); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); // test get Disk remoteDisk = compute.getDisk(diskId); assertNotNull(remoteDisk); @@ -910,7 +896,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.resize(200L); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); // test resize and get with selected fields remoteDisk = compute.getDisk(diskId, Compute.DiskOption.fields(Compute.DiskField.SIZE_GB)); assertNotNull(remoteDisk); @@ -926,7 +912,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.delete(); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); assertNull(compute.getDisk(diskId)); } @@ -936,7 +922,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { DiskId diskId = DiskId.of(ZONE, name); DiskInfo diskInfo = DiskInfo.of(diskId, ImageDiskConfiguration.of(IMAGE_ID)); Operation operation = compute.create(diskInfo); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); // test get Disk remoteDisk = compute.getDisk(diskId); assertNotNull(remoteDisk); @@ -971,7 +957,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.delete(); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); assertNull(compute.getDisk(diskId)); } @@ -985,10 +971,10 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx DiskInfo diskInfo = DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); Operation operation = compute.create(diskInfo); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); Disk remoteDisk = compute.getDisk(diskId); operation = remoteDisk.createSnapshot(snapshotName); - operation.whenDone(EMPTY_CALLBACK); + operation.waitFor(); // test get snapshot with selected fields Snapshot snapshot = compute.getSnapshot(snapshotName, Compute.SnapshotOption.fields(Compute.SnapshotField.CREATION_TIMESTAMP)); @@ -1018,7 +1004,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx diskInfo = DiskInfo.of(snapshotDiskId, SnapshotDiskConfiguration.of(SnapshotId.of(snapshotName))); operation = compute.create(diskInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); // test get disk remoteDisk = compute.getDisk(snapshotDiskId); assertNotNull(remoteDisk); @@ -1054,10 +1040,10 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.delete(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getDisk(snapshotDiskId)); operation = snapshot.delete(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getSnapshot(snapshotName)); } @@ -1071,8 +1057,8 @@ public void testListDisksAndSnapshots() throws InterruptedException { StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L); Operation firstOperation = compute.create(DiskInfo.of(firstDiskId, configuration)); Operation secondOperation = compute.create(DiskInfo.of(secondDiskId, configuration)); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); Set diskSet = ImmutableSet.copyOf(diskNames); // test list disks Compute.DiskFilter diskFilter = @@ -1124,8 +1110,8 @@ public void testListDisksAndSnapshots() throws InterruptedException { SnapshotId secondSnapshotId = SnapshotId.of(diskNames[1]); firstOperation = compute.create(SnapshotInfo.of(firstSnapshotId, firstDiskId)); secondOperation = compute.create(SnapshotInfo.of(secondSnapshotId, secondDiskId)); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); // test list snapshots Compute.SnapshotFilter snapshotFilter = Compute.SnapshotFilter.equals(Compute.SnapshotField.NAME, prefix + "\\d"); @@ -1183,8 +1169,8 @@ public void testAggregatedListDisks() throws InterruptedException { StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L); Operation firstOperation = compute.create(DiskInfo.of(firstDiskId, configuration)); Operation secondOperation = compute.create(DiskInfo.of(secondDiskId, configuration)); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); Set zoneSet = ImmutableSet.copyOf(diskZones); Set diskSet = ImmutableSet.copyOf(diskNames); Compute.DiskFilter diskFilter = @@ -1220,11 +1206,11 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { DiskInfo diskInfo = DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); Operation operation = compute.create(diskInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); Disk remoteDisk = compute.getDisk(diskId); ImageInfo imageInfo = ImageInfo.of(imageId, DiskImageConfiguration.of(diskId)); operation = compute.create(imageInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); // test get image with selected fields Image image = compute.getImage(imageId, Compute.ImageOption.fields(Compute.ImageField.CREATION_TIMESTAMP)); @@ -1260,12 +1246,12 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { .deprecated(System.currentTimeMillis()) .build(); operation = image.deprecate(deprecationStatus); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); image = compute.getImage(imageId); assertEquals(deprecationStatus, image.deprecationStatus()); remoteDisk.delete(); operation = image.delete(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getImage(imageId)); } @@ -1336,7 +1322,7 @@ public void testCreateAndGetNetwork() throws InterruptedException { NetworkInfo networkInfo = NetworkInfo.of(networkId, StandardNetworkConfiguration.of("192.168.0.0/16")); Operation operation = compute.create(networkInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); // test get network with selected fields Network network = compute.getNetwork(networkId.network(), Compute.NetworkOption.fields(Compute.NetworkField.CREATION_TIMESTAMP)); @@ -1356,7 +1342,7 @@ public void testCreateAndGetNetwork() throws InterruptedException { remoteConfiguration = network.configuration(); assertEquals("192.168.0.0/16", remoteConfiguration.ipRange()); operation = network.delete(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getNetwork(name)); } @@ -1367,7 +1353,7 @@ public void testListNetworks() throws InterruptedException { NetworkInfo networkInfo = NetworkInfo.of(networkId, StandardNetworkConfiguration.of("192.168.0.0/16")); Operation operation = compute.create(networkInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); // test list Compute.NetworkFilter filter = Compute.NetworkFilter.equals(Compute.NetworkField.NAME, name); Page networkPage = compute.listNetworks(Compute.NetworkListOption.filter(filter)); @@ -1402,7 +1388,7 @@ public void testListNetworks() throws InterruptedException { } assertEquals(1, count); operation = compute.deleteNetwork(networkId); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getNetwork(name)); } @@ -1412,7 +1398,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { NetworkId networkId = NetworkId.of(networkName); NetworkInfo networkInfo = NetworkInfo.of(networkId, SubnetNetworkConfiguration.of(false)); Operation operation = compute.create(networkInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); // test get network Network network = compute.getNetwork(networkId.network()); assertEquals(networkId.network(), network.networkId().network()); @@ -1425,7 +1411,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { SubnetworkId subnetworkId = SubnetworkId.of(REGION, subnetworkName); SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(subnetworkId, networkId, "192.168.0.0/16"); operation = compute.create(subnetworkInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); // test get subnetwork with selected fields Subnetwork subnetwork = compute.getSubnetwork(subnetworkId, Compute.SubnetworkOption.fields(Compute.SubnetworkField.CREATION_TIMESTAMP)); @@ -1480,9 +1466,9 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { } assertEquals(1, count); operation = subnetwork.delete(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); operation = compute.deleteNetwork(networkId); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getSubnetwork(subnetworkId)); assertNull(compute.getNetwork(networkName)); } @@ -1493,7 +1479,7 @@ public void testAggregatedListSubnetworks() throws InterruptedException { NetworkId networkId = NetworkId.of(networkName); NetworkInfo networkInfo = NetworkInfo.of(networkId, SubnetNetworkConfiguration.of(false)); Operation operation = compute.create(networkInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); String prefix = BASE_RESOURCE_NAME + "list-subnetwork"; String[] regionNames = {"us-central1", "us-east1"}; String[] subnetworkNames = {prefix + "1", prefix + "2"}; @@ -1506,8 +1492,8 @@ public void testAggregatedListSubnetworks() throws InterruptedException { SubnetworkInfo.of(secondSubnetworkId, networkId, ipRanges[1]); Operation firstOperation = compute.create(firstSubnetworkInfo); Operation secondOperation = compute.create(secondSubnetworkInfo); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); Set regionSet = ImmutableSet.copyOf(regionNames); Set subnetworkSet = ImmutableSet.copyOf(subnetworkNames); Set rangeSet = ImmutableSet.copyOf(ipRanges); @@ -1531,10 +1517,10 @@ public void testAggregatedListSubnetworks() throws InterruptedException { assertEquals(2, count); firstOperation = compute.deleteSubnetwork(firstSubnetworkId); secondOperation = compute.deleteSubnetwork(secondSubnetworkId); - firstOperation.whenDone(EMPTY_CALLBACK); - secondOperation.whenDone(EMPTY_CALLBACK); + firstOperation.waitFor(); + secondOperation.waitFor(); operation = compute.deleteNetwork(networkId); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getNetwork(networkName)); } @@ -1546,7 +1532,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { AddressId addressId = RegionAddressId.of(REGION, addressName); AddressInfo addressInfo = AddressInfo.of(addressId); Operation operation = compute.create(addressInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); Address address = compute.getAddress(addressId); // Create an instance InstanceId instanceId = InstanceId.of(ZONE, instanceName); @@ -1564,7 +1550,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { .networkInterfaces(networkInterface) .build(); operation = compute.create(instanceInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); // test get Instance remoteInstance = compute.getInstance(instanceId); assertEquals(instanceName, remoteInstance.instanceId().instance()); @@ -1616,7 +1602,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { String newSerialPortOutput = remoteInstance.getSerialPortOutput(1); assertTrue(newSerialPortOutput.contains(serialPortOutput)); operation = remoteInstance.delete(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); assertNull(compute.getInstance(instanceId)); address.delete(); } @@ -1635,22 +1621,22 @@ public void testStartStopAndResetInstance() throws InterruptedException { .networkInterfaces(networkInterface) .build(); Operation operation = compute.create(instanceInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); Instance remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); operation = remoteInstance.stop(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.TERMINATED, remoteInstance.status()); operation = remoteInstance.start(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); operation = remoteInstance.reset(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); @@ -1671,32 +1657,32 @@ public void testSetInstanceProperties() throws InterruptedException { .networkInterfaces(networkInterface) .build(); Operation operation = compute.create(instanceInfo); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); Instance remoteInstance = compute.getInstance(instanceId); // test set tags List tags = ImmutableList.of("tag1", "tag2"); operation = remoteInstance.setTags(tags); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(tags, remoteInstance.tags().values()); // test set metadata Map metadata = ImmutableMap.of("key", "value"); operation = remoteInstance.setMetadata(metadata); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(metadata, remoteInstance.metadata().values()); // test set machine type operation = remoteInstance.stop(); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); operation = remoteInstance.setMachineType(MachineTypeId.of(ZONE, "n1-standard-1")); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals("n1-standard-1", remoteInstance.machineType().type()); assertEquals(ZONE, remoteInstance.machineType().zone()); // test set scheduling options SchedulingOptions options = SchedulingOptions.standard(false, SchedulingOptions.Maintenance.TERMINATE); operation = remoteInstance.setSchedulingOptions(options); -operation.whenDone(EMPTY_CALLBACK); +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(options, remoteInstance.schedulingOptions()); remoteInstance.delete(); @@ -1720,13 +1706,13 @@ public void testAttachAndDetachDisk() throws InterruptedException { DiskId diskId = DiskId.of(ZONE, diskName); Operation diskOperation = compute.create(DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd")))); - instanceOperation.whenDone(EMPTY_CALLBACK); - diskOperation.whenDone(EMPTY_CALLBACK); + instanceOperation.waitFor(); + diskOperation.waitFor(); Instance remoteInstance = compute.getInstance(instanceId); // test attach disk instanceOperation = remoteInstance.attachDisk("dev1", AttachedDisk.PersistentDiskConfiguration.builder(diskId).build()); - instanceOperation.whenDone(EMPTY_CALLBACK); + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); Set deviceSet = ImmutableSet.of("dev0", "dev1"); assertEquals(2, remoteInstance.attachedDisks().size()); @@ -1735,7 +1721,7 @@ public void testAttachAndDetachDisk() throws InterruptedException { } // test set disk auto-delete instanceOperation = remoteInstance.setDiskAutoDelete("dev1", true); - instanceOperation.whenDone(EMPTY_CALLBACK); + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(2, remoteInstance.attachedDisks().size()); for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { @@ -1744,7 +1730,7 @@ public void testAttachAndDetachDisk() throws InterruptedException { } // test detach disk instanceOperation = remoteInstance.detachDisk("dev1"); - instanceOperation.whenDone(EMPTY_CALLBACK); + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(1, remoteInstance.attachedDisks().size()); assertEquals("dev0", remoteInstance.attachedDisks().get(0).deviceName()); @@ -1770,8 +1756,8 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { AddressId addressId = RegionAddressId.of(REGION, addressName); AddressInfo addressInfo = AddressInfo.of(addressId); Operation addressOperation = compute.create(addressInfo); - addressOperation.whenDone(EMPTY_CALLBACK); - instanceOperation.whenDone(EMPTY_CALLBACK); + addressOperation.waitFor(); + instanceOperation.waitFor(); Address remoteAddress = compute.getAddress(addressId); Instance remoteInstance = compute.getInstance(instanceId); String networkInterfaceName = remoteInstance.networkInterfaces().get(0).name(); @@ -1781,7 +1767,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { .name("NAT") .build(); instanceOperation = remoteInstance.addAccessConfig(networkInterfaceName, accessConfig); - instanceOperation.whenDone(EMPTY_CALLBACK); + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); List accessConfigurations = remoteInstance.networkInterfaces().get(0).accessConfigurations(); @@ -1789,7 +1775,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { assertEquals("NAT", accessConfigurations.get(0).name()); // test delete access config instanceOperation = remoteInstance.deleteAccessConfig(networkInterfaceName, "NAT"); - instanceOperation.whenDone(EMPTY_CALLBACK); + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertTrue(remoteInstance.networkInterfaces().get(0).accessConfigurations().isEmpty()); remoteInstance.delete(); diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java index 41cacef7ed00..156e475a5ac9 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java @@ -523,19 +523,18 @@ private abstract static class JobRunAction extends BigQueryAction { @Override void run(BigQuery bigquery, JobInfo job) throws Exception { System.out.println("Creating job"); - final Job startedJob = bigquery.create(job); - startedJob.whenDone(new Job.CompletionCallback() { - @Override - public void success(Job updatedJob) { - System.out.println("Job " + updatedJob.jobId().job() + " succeeded"); - } - - @Override - public void error(BigQueryError error, List executionErrors) { - System.out.println("Job " + startedJob.jobId().job() + " failed"); - System.out.println("Error: " + startedJob.status().error()); - } - }); + Job startedJob = bigquery.create(job); + while (!startedJob.isDone()) { + System.out.println("Waiting for job " + startedJob.jobId().job() + " to complete"); + Thread.sleep(1000L); + } + startedJob = startedJob.reload(); + if (startedJob.status().error() == null) { + System.out.println("Job " + startedJob.jobId().job() + " succeeded"); + } else { + System.out.println("Job " + startedJob.jobId().job() + " failed"); + System.out.println("Error: " + startedJob.status().error()); + } } } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java index e74bbc3723cc..8dd76b0265f8 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java @@ -23,7 +23,6 @@ package com.google.cloud.examples.bigquery.snippets; import com.google.cloud.bigquery.BigQuery; -import com.google.cloud.bigquery.BigQueryError; import com.google.cloud.bigquery.BigQueryOptions; import com.google.cloud.bigquery.Field; import com.google.cloud.bigquery.FormatOptions; @@ -34,8 +33,6 @@ import com.google.cloud.bigquery.TableId; import com.google.cloud.bigquery.TableInfo; -import java.util.List; - /** * A snippet for Google Cloud BigQuery showing how to get a BigQuery table or create it if it does * not exist. The snippet also starts a BigQuery job to load data into the table from a Cloud @@ -55,16 +52,11 @@ public static void main(String... args) throws InterruptedException { } System.out.println("Loading data into table " + tableId); Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path"); - loadJob.whenDone(new Job.CompletionCallback() { - @Override - public void success(Job job) { - System.out.println("Job succeeded"); - } - - @Override - public void error(BigQueryError error, List executionErrors) { - System.out.println("Job completed with errors"); - } - }); + loadJob = loadJob.waitFor(); + if (loadJob.status().error() != null) { + System.out.println("Job completed with errors"); + } else { + System.out.println("Job succeeded"); + } } } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java index 4948f68b6db8..04d2116e0a75 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java @@ -33,12 +33,8 @@ import com.google.cloud.compute.NetworkInterface; import com.google.cloud.compute.NetworkInterface.AccessConfig; import com.google.cloud.compute.Operation; -import com.google.cloud.compute.Operation.OperationError; -import com.google.cloud.compute.Operation.OperationWarning; import com.google.cloud.compute.RegionAddressId; -import java.util.List; - /** * A snippet for Google Cloud Compute Engine showing how to create a disk and an address. The * snippet also shows how to create a virtual machine instance using the created disk and address. @@ -54,18 +50,13 @@ public static void main(String... args) throws InterruptedException { final RegionAddressId addressId = RegionAddressId.of("us-central1", "test-address"); Operation operation = compute.create(AddressInfo.of(addressId)); // Wait for operation to complete - operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - System.out.println("Address " + addressId + " was successfully created"); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Address creation failed"); - } - }); + operation = operation.waitFor(); + if (operation.errors() == null) { + System.out.println("Address " + addressId + " was successfully created"); + } else { + // inspect operation.errors() + throw new RuntimeException("Address creation failed"); + } // Create a persistent disk ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); @@ -74,18 +65,13 @@ public void error(List errors, List warnings) DiskInfo disk = DiskInfo.of(diskId, diskConfiguration); operation = compute.create(disk); // Wait for operation to complete - operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - System.out.println("Disk " + diskId + " was successfully created"); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Disk creation failed"); - } - }); + operation = operation.waitFor(); + if (operation.errors() == null) { + System.out.println("Disk " + diskId + " was successfully created"); + } else { + // inspect operation.errors() + throw new RuntimeException("Disk creation failed"); + } // Create a virtual machine instance Address externalIp = compute.getAddress(addressId); @@ -102,17 +88,12 @@ public void error(List errors, List warnings) InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface); operation = compute.create(instance); // Wait for operation to complete - operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - System.out.println("Instance " + instanceId + " was successfully created"); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Instance creation failed"); - } - }); + operation = operation.waitFor(); + if (operation.errors() == null) { + System.out.println("Instance " + instanceId + " was successfully created"); + } else { + // inspect operation.errors() + throw new RuntimeException("Instance creation failed"); + } } } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java index 0e70aa2ea83f..c144edcd3042 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java @@ -27,10 +27,6 @@ import com.google.cloud.compute.NetworkId; import com.google.cloud.compute.NetworkInterface; import com.google.cloud.compute.Operation; -import com.google.cloud.compute.Operation.OperationError; -import com.google.cloud.compute.Operation.OperationWarning; - -import java.util.List; /** * A snippet for Google Cloud Compute Engine showing how to create a virtual machine instance. @@ -47,18 +43,10 @@ public static void main(String... args) throws InterruptedException { MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); Operation operation = compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); - operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - // use instance - Instance instance = compute.getInstance(instanceId); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Instance creation failed"); - } - }); + operation = operation.waitFor(); + if (operation.errors() == null) { + // use instance + Instance instance = compute.getInstance(instanceId); + } } } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java index 1c364bf0c353..5f74f1a37fb7 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java @@ -21,12 +21,8 @@ import com.google.cloud.compute.Disk; import com.google.cloud.compute.DiskId; import com.google.cloud.compute.Operation; -import com.google.cloud.compute.Operation.OperationError; -import com.google.cloud.compute.Operation.OperationWarning; import com.google.cloud.compute.Snapshot; -import java.util.List; - /** * A snippet for Google Cloud Compute Engine showing how to create a snapshot of a disk if the disk * exists. @@ -40,19 +36,11 @@ public static void main(String... args) throws InterruptedException { if (disk != null) { final String snapshotName = "disk-name-snapshot"; Operation operation = disk.createSnapshot(snapshotName); - operation.whenDone(new Operation.CompletionCallback() { - @Override - public void success(Operation operation) { - // use snapshot - Snapshot snapshot = compute.getSnapshot(snapshotName); - } - - @Override - public void error(List errors, List warnings) { - // inspect errors - throw new RuntimeException("Snaphsot creation failed"); - } - }); + operation = operation.waitFor(); + if (operation.errors() == null) { + // use snapshot + Snapshot snapshot = compute.getSnapshot(snapshotName); + } } } }