Skip to content

Commit

Permalink
Third concept of DNS batch. (googleapis#787)
Browse files Browse the repository at this point in the history
* Added third concept of DNS batch.

* Simplified the internals. Removed DnsBatch.Request.

* Work in progress. Implemented more calls and added tests.

* Turned BatchResult into an abstract class.

* Created RpcBatch interface for opacity of batch.
Added core unit test for BatchResult.
Added javadoc for BatchResult generics.
Changed prefix of newCallback methods.
Fixed method javadoc.

* Fixed documentation.

* Removed addToBatch methods from RPC.

* Removed conflicts with master branch.

* Implemented batch processing for change requests and record sets.

* Implemented the rest of the batch functions and tests.

- Renames several forgotten DnsRecord variables and functions in tests
- Moved the Callback interface from DnsRpc to RpcBatch

* Added tests for callbacks. Fixed documentation.

* Added onFailure callback tests and fixed one doc string.

* Extracted GoogleJsonError to a final attribute.

* Fixed imports and implemented notify.

* Fixed import orders

* Annotated getters as @VisibleForTesting.

* Fixed docs and renamed a few methods.

Also consolidated mocks batch in tests.

* Added notify test

* Renamed submitted() to completed().

* Consolidated more tests and added exception to notify.

* Added test for null result in BatchResult.
  • Loading branch information
mderka authored and mziccard committed Apr 19, 2016
1 parent 5e0de55 commit c95e1ec
Show file tree
Hide file tree
Showing 17 changed files with 1,772 additions and 72 deletions.
106 changes: 106 additions & 0 deletions gcloud-java-core/src/main/java/com/google/cloud/BatchResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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;

import static com.google.common.base.Preconditions.checkState;

import java.util.LinkedList;
import java.util.List;

/**
* This class holds a single result of a batch call. {@code T} is the type of the result and {@code
* E} is the type of the service-dependent exception thrown when a processing error occurs.
*/
public abstract class BatchResult<T, E extends BaseServiceException> {

private T result;
private boolean completed = false;
private E error;
private List<Callback<T, E>> toBeNotified = new LinkedList<>();

/**
* Returns {@code true} if the batch has been completed and the result is available; {@code false}
* otherwise.
*/
public boolean completed() {
return completed;
}

/**
* Returns the result of this call.
*
* @throws IllegalStateException if the batch has not been completed yet
* @throws E if an error occurred when processing this request
*/
public T get() throws E {
checkState(completed(), "Batch has not been completed yet");
if (error != null) {
throw error;
}
return result;
}

/**
* Adds a callback for the batch operation.
*
* @throws IllegalStateException if the batch has been completed already
*/
public void notify(Callback<T, E> callback) {
if (completed) {
throw new IllegalStateException("The batch has been completed. All the calls to the notify()"
+ " method should be done prior to submitting the batch.");
}
toBeNotified.add(callback);
}

/**
* Sets an error and status as completed. Notifies all callbacks.
*/
protected void error(E error) {
this.error = error;
this.completed = true;
for (Callback<T, E> callback : toBeNotified) {
callback.error(error);
}
}

/**
* Sets a result and status as completed. Notifies all callbacks.
*/
protected void success(T result) {
this.result = result;
this.completed = true;
for (Callback<T, E> callback : toBeNotified) {
callback.success(result);
}
}

/**
* An interface for the batch callbacks.
*/
public interface Callback<T, E> {
/**
* The method to be called when the batched operation succeeds.
*/
void success(T result);

/**
* The method to be called when the batched operation fails.
*/
void error(E exception);
}
}
107 changes: 107 additions & 0 deletions gcloud-java-core/src/test/java/com/google/cloud/BatchResultTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;

public class BatchResultTest {

private BatchResult<Boolean, BaseServiceException> result;

@Before
public void setUp() {
result = new BatchResult<Boolean, BaseServiceException>() {};
}

@Test
public void testSuccess() {
assertFalse(result.completed());
try {
result.get();
fail("This was not completed yet.");
} catch (IllegalStateException ex) {
// expected
}
result.success(true);
assertTrue(result.get());
// test that null is allowed
result.success(null);
}

@Test
public void testError() {
assertFalse(result.completed());
try {
result.get();
fail("This was not completed yet.");
} catch (IllegalStateException ex) {
// expected
}
BaseServiceException ex = new BaseServiceException(0, "message", "reason", false);
result.error(ex);
try {
result.get();
fail("This is a failed operation and should have thrown a DnsException.");
} catch (BaseServiceException real) {
assertSame(ex, real);
}
}

@Test
public void testNotifyError() {
final BaseServiceException ex = new BaseServiceException(0, "message", "reason", false);
assertFalse(result.completed());
BatchResult.Callback<Boolean, BaseServiceException> callback =
EasyMock.createStrictMock(BatchResult.Callback.class);
callback.error(ex);
EasyMock.replay(callback);
result.notify(callback);
result.error(ex);
try {
result.notify(callback);
fail("The batch has been completed.");
} catch (IllegalStateException exception) {
// expected
}
EasyMock.verify(callback);
}

@Test
public void testNotifySuccess() {
assertFalse(result.completed());
BatchResult.Callback<Boolean, BaseServiceException> callback =
EasyMock.createStrictMock(BatchResult.Callback.class);
callback.success(true);
EasyMock.replay(callback);
result.notify(callback);
result.success(true);
try {
result.notify(callback);
fail("The batch has been completed.");
} catch (IllegalStateException exception) {
// expected
}
EasyMock.verify(callback);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ public ChangeRequest reload(Dns.ChangeRequestOption... options) {

/**
* Returns {@code true} if the change request has been completed. If the status is not {@link
* Status#DONE} already, the method makes an API call to Google Cloud DNS to update the change
* request first.
* ChangeRequestInfo.Status#DONE} already, the method makes an API call to Google Cloud DNS to
* update the change request first.
*
* @throws DnsException upon failure of the API call or if the associated zone was not found
*/
Expand Down
5 changes: 5 additions & 0 deletions gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java
Original file line number Diff line number Diff line change
Expand Up @@ -503,4 +503,9 @@ ChangeRequest getChangeRequest(String zoneName, String changeRequestId,
* @see <a href="https://cloud.google.com/dns/api/v1/changes/list">Cloud DNS Chages: list</a>
*/
Page<ChangeRequest> listChangeRequests(String zoneName, ChangeRequestListOption... options);

/**
* Creates a new empty batch for grouping multiple service calls in one underlying RPC call.
*/
DnsBatch batch();
}
Loading

0 comments on commit c95e1ec

Please sign in to comment.