Skip to content

Commit e213176

Browse files
committed
Add support for batches to DNS (#940)
1 parent 5e0de55 commit e213176

File tree

20 files changed

+3942
-153
lines changed

20 files changed

+3942
-153
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud;
18+
19+
import static com.google.common.base.Preconditions.checkNotNull;
20+
import static com.google.common.base.Preconditions.checkState;
21+
22+
import java.util.LinkedList;
23+
import java.util.List;
24+
25+
/**
26+
* This class holds a single result of a batch call. The class is not thread-safe.
27+
*
28+
* @param <T> the type of the result
29+
* @param <E> the type of the service-dependent exception thrown when a processing error occurs
30+
*
31+
*/
32+
public abstract class BatchResult<T, E extends BaseServiceException> {
33+
34+
private T result;
35+
private boolean completed = false;
36+
private E error;
37+
private final List<Callback<T, E>> toBeNotified = new LinkedList<>();
38+
39+
/**
40+
* Returns {@code true} if the batch has been completed and the result is available; {@code false}
41+
* otherwise.
42+
*/
43+
public boolean completed() {
44+
return completed;
45+
}
46+
47+
/**
48+
* Returns the result of this call.
49+
*
50+
* @throws IllegalStateException if the batch has not been completed yet
51+
* @throws E if an error occurred when processing the batch request
52+
*/
53+
public T get() throws E {
54+
checkState(completed(), "Batch has not been completed yet");
55+
if (error != null) {
56+
throw error;
57+
}
58+
return result;
59+
}
60+
61+
/**
62+
* Adds a callback for the batch operation.
63+
*
64+
* @throws IllegalStateException if the batch has been completed already
65+
*/
66+
public void notify(Callback<T, E> callback) {
67+
checkState(!completed, "The batch has been completed. All the calls to the notify()"
68+
+ " method should be done prior to submitting the batch.");
69+
toBeNotified.add(callback);
70+
}
71+
72+
/**
73+
* Sets an error and status as completed. Notifies all callbacks.
74+
*/
75+
protected void error(E error) {
76+
this.error = checkNotNull(error);
77+
this.completed = true;
78+
for (Callback<T, E> callback : toBeNotified) {
79+
callback.error(error);
80+
}
81+
}
82+
83+
/**
84+
* Sets a result and status as completed. Notifies all callbacks.
85+
*/
86+
protected void success(T result) {
87+
this.result = result;
88+
this.completed = true;
89+
for (Callback<T, E> callback : toBeNotified) {
90+
callback.success(result);
91+
}
92+
}
93+
94+
/**
95+
* An interface for the batch callbacks.
96+
*/
97+
public interface Callback<T, E> {
98+
/**
99+
* The method to be called when the batched operation succeeds.
100+
*/
101+
void success(T result);
102+
103+
/**
104+
* The method to be called when the batched operation fails.
105+
*/
106+
void error(E exception);
107+
}
108+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud;
18+
19+
import static org.junit.Assert.assertFalse;
20+
import static org.junit.Assert.assertSame;
21+
import static org.junit.Assert.assertTrue;
22+
import static org.junit.Assert.fail;
23+
24+
import org.easymock.EasyMock;
25+
import org.junit.Before;
26+
import org.junit.Test;
27+
28+
public class BatchResultTest {
29+
30+
private BatchResult<Boolean, BaseServiceException> result;
31+
32+
@Before
33+
public void setUp() {
34+
result = new BatchResult<Boolean, BaseServiceException>() {};
35+
}
36+
37+
@Test
38+
public void testSuccess() {
39+
assertFalse(result.completed());
40+
try {
41+
result.get();
42+
fail("This was not completed yet.");
43+
} catch (IllegalStateException ex) {
44+
// expected
45+
}
46+
result.success(true);
47+
assertTrue(result.get());
48+
// test that null is allowed
49+
result.success(null);
50+
}
51+
52+
@Test
53+
public void testError() {
54+
assertFalse(result.completed());
55+
try {
56+
result.get();
57+
fail("This was not completed yet.");
58+
} catch (IllegalStateException ex) {
59+
// expected
60+
}
61+
try {
62+
result.error(null);
63+
fail();
64+
} catch (NullPointerException exc) {
65+
// expected
66+
}
67+
BaseServiceException ex = new BaseServiceException(0, "message", "reason", false);
68+
result.error(ex);
69+
try {
70+
result.get();
71+
fail("This is a failed operation and should have thrown a DnsException.");
72+
} catch (BaseServiceException real) {
73+
assertSame(ex, real);
74+
}
75+
}
76+
77+
@Test
78+
public void testNotifyError() {
79+
final BaseServiceException ex = new BaseServiceException(0, "message", "reason", false);
80+
assertFalse(result.completed());
81+
BatchResult.Callback<Boolean, BaseServiceException> callback =
82+
EasyMock.createStrictMock(BatchResult.Callback.class);
83+
callback.error(ex);
84+
EasyMock.replay(callback);
85+
result.notify(callback);
86+
result.error(ex);
87+
try {
88+
result.notify(callback);
89+
fail("The batch has been completed.");
90+
} catch (IllegalStateException exception) {
91+
// expected
92+
}
93+
EasyMock.verify(callback);
94+
}
95+
96+
@Test
97+
public void testNotifySuccess() {
98+
assertFalse(result.completed());
99+
BatchResult.Callback<Boolean, BaseServiceException> callback =
100+
EasyMock.createStrictMock(BatchResult.Callback.class);
101+
callback.success(true);
102+
EasyMock.replay(callback);
103+
result.notify(callback);
104+
result.success(true);
105+
try {
106+
result.notify(callback);
107+
fail("The batch has been completed.");
108+
} catch (IllegalStateException exception) {
109+
// expected
110+
}
111+
EasyMock.verify(callback);
112+
}
113+
}

gcloud-java-dns/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
</exclusion>
4141
</exclusions>
4242
</dependency>
43+
<dependency>
44+
<groupId>commons-fileupload</groupId>
45+
<artifactId>commons-fileupload</artifactId>
46+
<version>1.3.1</version>
47+
</dependency>
4348
<dependency>
4449
<groupId>${project.groupId}</groupId>
4550
<artifactId>gcloud-java-core</artifactId>

gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ public ChangeRequest reload(Dns.ChangeRequestOption... options) {
173173

174174
/**
175175
* Returns {@code true} if the change request has been completed. If the status is not {@link
176-
* Status#DONE} already, the method makes an API call to Google Cloud DNS to update the change
177-
* request first.
176+
* ChangeRequestInfo.Status#DONE} already, the method makes an API call to Google Cloud DNS to
177+
* update the change request first.
178178
*
179179
* @throws DnsException upon failure of the API call or if the associated zone was not found
180180
*/

gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,4 +503,9 @@ ChangeRequest getChangeRequest(String zoneName, String changeRequestId,
503503
* @see <a href="https://cloud.google.com/dns/api/v1/changes/list">Cloud DNS Chages: list</a>
504504
*/
505505
Page<ChangeRequest> listChangeRequests(String zoneName, ChangeRequestListOption... options);
506+
507+
/**
508+
* Creates a new empty batch for grouping multiple service calls in one underlying RPC call.
509+
*/
510+
DnsBatch batch();
506511
}

0 commit comments

Comments
 (0)