Use mutation methods for stub reconfiguration.

This makes the reconfiguration code more concise.

- Remove configureNewStub().
- Add mutation methods withDeadlineNanoTime(), withChannel() etc that
  returns the reconfigured stub.
This commit is contained in:
Kun Zhang 2015-07-22 16:52:28 -07:00
parent afdbe19937
commit 60cf5eb5da
4 changed files with 44 additions and 88 deletions

View File

@ -588,9 +588,7 @@ public abstract class AbstractTransportTest {
public void sendsTimeoutHeader() { public void sendsTimeoutHeader() {
long configuredTimeoutMinutes = 100; long configuredTimeoutMinutes = 100;
TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel) TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel)
.configureNewStub() .withDeadlineAfter(configuredTimeoutMinutes, TimeUnit.MINUTES);
.setDeadlineAfter(configuredTimeoutMinutes, TimeUnit.MINUTES)
.build();
stub.emptyCall(Empty.getDefaultInstance()); stub.emptyCall(Empty.getDefaultInstance());
long transferredTimeoutMinutes = TimeUnit.MICROSECONDS.toMinutes( long transferredTimeoutMinutes = TimeUnit.MICROSECONDS.toMinutes(
requestHeadersCapture.get().get(ChannelImpl.TIMEOUT_KEY)); requestHeadersCapture.get().get(ChannelImpl.TIMEOUT_KEY));
@ -607,9 +605,8 @@ public abstract class AbstractTransportTest {
// warm up the channel and JVM // warm up the channel and JVM
blockingStub.emptyCall(Empty.getDefaultInstance()); blockingStub.emptyCall(Empty.getDefaultInstance());
TestServiceGrpc.newBlockingStub(channel) TestServiceGrpc.newBlockingStub(channel)
.configureNewStub() .withDeadlineAfter(50, TimeUnit.MILLISECONDS)
.setDeadlineAfter(50, TimeUnit.MILLISECONDS) .emptyCall(Empty.getDefaultInstance());
.build().emptyCall(Empty.getDefaultInstance());
} }
@Test(timeout = 10000) @Test(timeout = 10000)
@ -618,9 +615,7 @@ public abstract class AbstractTransportTest {
// warm up the channel and JVM // warm up the channel and JVM
blockingStub.emptyCall(Empty.getDefaultInstance()); blockingStub.emptyCall(Empty.getDefaultInstance());
TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel) TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel)
.configureNewStub() .withDeadlineAfter(10, TimeUnit.MILLISECONDS);
.setDeadlineAfter(10, TimeUnit.MILLISECONDS)
.build();
try { try {
stub.emptyCall(Empty.getDefaultInstance()); stub.emptyCall(Empty.getDefaultInstance());
fail("Expected deadline to be exceeded"); fail("Expected deadline to be exceeded");
@ -647,9 +642,8 @@ public abstract class AbstractTransportTest {
.build(); .build();
StreamRecorder<StreamingOutputCallResponse> recorder = StreamRecorder.create(); StreamRecorder<StreamingOutputCallResponse> recorder = StreamRecorder.create();
TestServiceGrpc.newStub(channel) TestServiceGrpc.newStub(channel)
.configureNewStub() .withDeadlineAfter(30, TimeUnit.MILLISECONDS)
.setDeadlineAfter(30, TimeUnit.MILLISECONDS) .streamingOutputCall(request, recorder);
.build().streamingOutputCall(request, recorder);
recorder.awaitCompletion(); recorder.awaitCompletion();
assertEquals(Status.DEADLINE_EXCEEDED, Status.fromThrowable(recorder.getError())); assertEquals(Status.DEADLINE_EXCEEDED, Status.fromThrowable(recorder.getError()));
assertNotEquals(0, recorder.getValues().size()); assertNotEquals(0, recorder.getValues().size());
@ -723,9 +717,8 @@ public abstract class AbstractTransportTest {
GoogleCredentials credentials = GoogleCredentials credentials =
(ServiceAccountCredentials) GoogleCredentials.fromStream(credentialsStream); (ServiceAccountCredentials) GoogleCredentials.fromStream(credentialsStream);
credentials = credentials.createScoped(Arrays.<String>asList(authScope)); credentials = credentials.createScoped(Arrays.<String>asList(authScope));
TestServiceGrpc.TestServiceBlockingStub stub = blockingStub.configureNewStub() TestServiceGrpc.TestServiceBlockingStub stub = blockingStub
.addInterceptor(new ClientAuthInterceptor(credentials, testServiceExecutor)) .withInterceptors(new ClientAuthInterceptor(credentials, testServiceExecutor));
.build();
final SimpleRequest request = SimpleRequest.newBuilder() final SimpleRequest request = SimpleRequest.newBuilder()
.setFillUsername(true) .setFillUsername(true)
.setFillOauthScope(true) .setFillOauthScope(true)
@ -756,9 +749,8 @@ public abstract class AbstractTransportTest {
/** Sends a large unary rpc with compute engine credentials. */ /** Sends a large unary rpc with compute engine credentials. */
public void computeEngineCreds(String serviceAccount, String oauthScope) throws Exception { public void computeEngineCreds(String serviceAccount, String oauthScope) throws Exception {
ComputeEngineCredentials credentials = new ComputeEngineCredentials(); ComputeEngineCredentials credentials = new ComputeEngineCredentials();
TestServiceGrpc.TestServiceBlockingStub stub = blockingStub.configureNewStub() TestServiceGrpc.TestServiceBlockingStub stub = blockingStub
.addInterceptor(new ClientAuthInterceptor(credentials, testServiceExecutor)) .withInterceptors(new ClientAuthInterceptor(credentials, testServiceExecutor));
.build();
final SimpleRequest request = SimpleRequest.newBuilder() final SimpleRequest request = SimpleRequest.newBuilder()
.setFillUsername(true) .setFillUsername(true)
.setFillOauthScope(true) .setFillOauthScope(true)

View File

@ -87,8 +87,7 @@ public class StubConfigTest {
TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel); TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel);
assertNull(stub.getCallOptions().getDeadlineNanoTime()); assertNull(stub.getCallOptions().getDeadlineNanoTime());
// Reconfigure it // Reconfigure it
TestServiceGrpc.TestServiceBlockingStub reconfiguredStub = TestServiceGrpc.TestServiceBlockingStub reconfiguredStub = stub.withDeadlineNanoTime(2L);
stub.configureNewStub().setDeadlineNanoTime(2L).build();
// New altered config // New altered config
assertEquals(2L, (long) reconfiguredStub.getCallOptions().getDeadlineNanoTime()); assertEquals(2L, (long) reconfiguredStub.getCallOptions().getDeadlineNanoTime());
// Default config unchanged // Default config unchanged
@ -102,7 +101,7 @@ public class StubConfigTest {
SimpleRequest request = SimpleRequest.getDefaultInstance(); SimpleRequest request = SimpleRequest.getDefaultInstance();
stub.unaryCall(request, responseObserver); stub.unaryCall(request, responseObserver);
verify(channel).newCall(same(TestServiceGrpc.METHOD_UNARY_CALL), same(options1)); verify(channel).newCall(same(TestServiceGrpc.METHOD_UNARY_CALL), same(options1));
stub = stub.configureNewStub().setDeadlineNanoTime(2L).build(); stub = stub.withDeadlineNanoTime(2L);
CallOptions options2 = stub.getCallOptions(); CallOptions options2 = stub.getCallOptions();
assertNotSame(options1, options2); assertNotSame(options1, options2);
stub.unaryCall(request, responseObserver); stub.unaryCall(request, responseObserver);

View File

@ -36,8 +36,6 @@ import io.grpc.Channel;
import io.grpc.ClientInterceptor; import io.grpc.ClientInterceptor;
import io.grpc.ClientInterceptors; import io.grpc.ClientInterceptors;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -74,13 +72,6 @@ public abstract class AbstractStub<S extends AbstractStub<?>> {
this.callOptions = callOptions; this.callOptions = callOptions;
} }
/**
* Creates a builder for reconfiguring the stub.
*/
public StubConfigBuilder configureNewStub() {
return new StubConfigBuilder();
}
/** /**
* The underlying channel of the stub. * The underlying channel of the stub.
*/ */
@ -104,63 +95,38 @@ public abstract class AbstractStub<S extends AbstractStub<?>> {
protected abstract S build(Channel channel, CallOptions callOptions); protected abstract S build(Channel channel, CallOptions callOptions);
/** /**
* Utility class for (re) configuring the operations in a stub. * Returns a new stub with an absolute deadline in nanoseconds in the clock as per {@link
*/ * System#nanoTime()}.
public class StubConfigBuilder {
private final List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
private CallOptions callOptions = AbstractStub.this.callOptions;
private Channel stubChannel;
private StubConfigBuilder() {
this.stubChannel = AbstractStub.this.channel;
}
/**
* Sets an absolute deadline in nanoseconds in the clock as per {@link System#nanoTime()}.
* *
* <p>This is mostly used for propagating an existing deadline. {@link #setDeadlineAfter} is the * <p>This is mostly used for propagating an existing deadline. {@link #withDeadlineAfter} is the
* recommended way of setting a new deadline, * recommended way of setting a new deadline,
* *
* @param deadlineNanoTime nanoseconds in the clock as per {@link System#nanoTime()} * @param deadlineNanoTime nanoseconds in the clock as per {@link System#nanoTime()}
*/ */
public StubConfigBuilder setDeadlineNanoTime(@Nullable Long deadlineNanoTime) { public final S withDeadlineNanoTime(@Nullable Long deadlineNanoTime) {
callOptions = callOptions.withDeadlineNanoTime(deadlineNanoTime); return build(channel, callOptions.withDeadlineNanoTime(deadlineNanoTime));
return this;
} }
/** /**
* Sets a deadline that is after the given {@code duration} from now. * Returns a new stub with a deadline that is after the given {@code duration} from now.
* *
* @see CallOptions#withDeadlineAfter * @see CallOptions#withDeadlineAfter
*/ */
public StubConfigBuilder setDeadlineAfter(long duration, TimeUnit unit) { public final S withDeadlineAfter(long duration, TimeUnit unit) {
callOptions = callOptions.withDeadlineAfter(duration, unit); return build(channel, callOptions.withDeadlineAfter(duration, unit));
return this;
} }
/** /**
* Set the channel to be used by the stub. * Returns a new stub that uses the given channel.
*/ */
public StubConfigBuilder setChannel(Channel channel) { public final S withChannel(Channel newChannel) {
this.stubChannel = channel; return build(newChannel, callOptions);
return this;
} }
/** /**
* Adds a client interceptor to be attached to the channel of the reconfigured stub. * Returns a new stub that has the given interceptors attached to the underlying channel.
*/ */
public StubConfigBuilder addInterceptor(ClientInterceptor interceptor) { public final S withInterceptors(ClientInterceptor... interceptors) {
interceptors.add(interceptor); return build(ClientInterceptors.intercept(channel, interceptors), callOptions);
return this;
}
/**
* Create a new stub with the configurations made on this builder.
*/
public S build() {
return AbstractStub.this.build(
ClientInterceptors.intercept(stubChannel, interceptors), callOptions);
}
} }
} }

View File

@ -59,8 +59,7 @@ public class MetadataUtils {
public static <T extends AbstractStub> T attachHeaders( public static <T extends AbstractStub> T attachHeaders(
T stub, T stub,
final Metadata.Headers extraHeaders) { final Metadata.Headers extraHeaders) {
return (T) stub.configureNewStub().addInterceptor( return (T) stub.withInterceptors(newAttachHeadersInterceptor(extraHeaders));
newAttachHeadersInterceptor(extraHeaders)).build();
} }
/** /**
@ -100,8 +99,8 @@ public class MetadataUtils {
T stub, T stub,
AtomicReference<Metadata.Headers> headersCapture, AtomicReference<Metadata.Headers> headersCapture,
AtomicReference<Metadata.Trailers> trailersCapture) { AtomicReference<Metadata.Trailers> trailersCapture) {
return (T) stub.configureNewStub().addInterceptor( return (T) stub.withInterceptors(
newCaptureMetadataInterceptor(headersCapture, trailersCapture)).build(); newCaptureMetadataInterceptor(headersCapture, trailersCapture));
} }
/** /**