okhttp: OkHttpChannelBuilder extends a public API class
diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java b/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java
index c06a525..a0a484a 100644
--- a/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java
+++ b/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java
@@ -23,13 +23,13 @@
import io.grpc.alts.AltsChannelBuilder;
import io.grpc.alts.ComputeEngineChannelBuilder;
import io.grpc.alts.GoogleDefaultChannelBuilder;
-import io.grpc.internal.AbstractManagedChannelImplBuilder;
import io.grpc.internal.GrpcUtil;
import io.grpc.internal.testing.TestUtils;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.InternalNettyChannelBuilder;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.okhttp.InternalOkHttpChannelBuilder;
import io.grpc.okhttp.OkHttpChannelBuilder;
import io.grpc.okhttp.internal.Platform;
import io.netty.handler.ssl.SslContext;
@@ -403,7 +403,7 @@
if (useAlts) {
return AltsChannelBuilder.forAddress(serverHost, serverPort);
}
- AbstractManagedChannelImplBuilder<?> builder;
+
if (!useOkHttp) {
SslContext sslContext = null;
if (useTestCa) {
@@ -429,34 +429,33 @@
// Disable the default census stats interceptor, use testing interceptor instead.
InternalNettyChannelBuilder.setStatsEnabled(nettyBuilder, false);
return nettyBuilder.intercept(createCensusStatsClientInterceptor());
- } else {
- OkHttpChannelBuilder okBuilder = OkHttpChannelBuilder.forAddress(serverHost, serverPort);
- if (serverHostOverride != null) {
- // Force the hostname to match the cert the server uses.
- okBuilder.overrideAuthority(
- GrpcUtil.authorityFromHostAndPort(serverHostOverride, serverPort));
- }
- if (useTls) {
- if (useTestCa) {
- try {
- SSLSocketFactory factory = TestUtils.newSslSocketFactoryForCa(
- Platform.get().getProvider(), TestUtils.loadCert("ca.pem"));
- okBuilder.sslSocketFactory(factory);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ }
+
+ OkHttpChannelBuilder okBuilder = OkHttpChannelBuilder.forAddress(serverHost, serverPort);
+ if (serverHostOverride != null) {
+ // Force the hostname to match the cert the server uses.
+ okBuilder.overrideAuthority(
+ GrpcUtil.authorityFromHostAndPort(serverHostOverride, serverPort));
+ }
+ if (useTls) {
+ if (useTestCa) {
+ try {
+ SSLSocketFactory factory = TestUtils.newSslSocketFactoryForCa(
+ Platform.get().getProvider(), TestUtils.loadCert("ca.pem"));
+ okBuilder.sslSocketFactory(factory);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
- } else {
- okBuilder.usePlaintext();
}
- if (fullStreamDecompression) {
- okBuilder.enableFullStreamDecompression();
- }
- builder = okBuilder;
+ } else {
+ okBuilder.usePlaintext();
+ }
+ if (fullStreamDecompression) {
+ okBuilder.enableFullStreamDecompression();
}
// Disable the default census stats interceptor, use testing interceptor instead.
- io.grpc.internal.TestingAccessor.setStatsEnabled(builder, false);
- return builder.intercept(createCensusStatsClientInterceptor());
+ InternalOkHttpChannelBuilder.setStatsEnabled(okBuilder, false);
+ return okBuilder.intercept(createCensusStatsClientInterceptor());
}
@Override
diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java
index 041c7ca..fc6e600 100644
--- a/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java
+++ b/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java
@@ -29,6 +29,7 @@
import io.grpc.internal.testing.TestUtils;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyServerBuilder;
+import io.grpc.okhttp.InternalOkHttpChannelBuilder;
import io.grpc.okhttp.OkHttpChannelBuilder;
import io.grpc.okhttp.internal.Platform;
import io.grpc.stub.StreamObserver;
@@ -102,7 +103,7 @@
throw new RuntimeException(e);
}
// Disable the default census stats interceptor, use testing interceptor instead.
- io.grpc.internal.TestingAccessor.setStatsEnabled(builder, false);
+ InternalOkHttpChannelBuilder.setStatsEnabled(builder, false);
return builder.intercept(createCensusStatsClientInterceptor());
}
diff --git a/okhttp/src/main/java/io/grpc/okhttp/InternalOkHttpChannelBuilder.java b/okhttp/src/main/java/io/grpc/okhttp/InternalOkHttpChannelBuilder.java
new file mode 100644
index 0000000..d328efd
--- /dev/null
+++ b/okhttp/src/main/java/io/grpc/okhttp/InternalOkHttpChannelBuilder.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 The gRPC Authors
+ *
+ * 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 io.grpc.okhttp;
+
+import io.grpc.Internal;
+
+/**
+ * Internal {@link OkHttpChannelBuilder} accessor. This is intended for usage internal to the gRPC
+ * team. If you *really* think you need to use this, contact the gRPC team first.
+ */
+@Internal
+public final class InternalOkHttpChannelBuilder {
+
+ public static void setStatsEnabled(OkHttpChannelBuilder builder, boolean value) {
+ builder.setStatsEnabled(value);
+ }
+
+ private InternalOkHttpChannelBuilder() {}
+}
diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
index 26a76f2..a775912 100644
--- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
+++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
@@ -24,13 +24,17 @@
import com.google.common.base.Preconditions;
import io.grpc.ChannelLogger;
import io.grpc.ExperimentalApi;
+import io.grpc.ForwardingChannelBuilder;
import io.grpc.Internal;
-import io.grpc.internal.AbstractManagedChannelImplBuilder;
+import io.grpc.ManagedChannelBuilder;
import io.grpc.internal.AtomicBackoff;
import io.grpc.internal.ClientTransportFactory;
import io.grpc.internal.ConnectionClientTransport;
import io.grpc.internal.GrpcUtil;
import io.grpc.internal.KeepAliveManager;
+import io.grpc.internal.ManagedChannelImplBuilder;
+import io.grpc.internal.ManagedChannelImplBuilder.ChannelBuilderDefaultPortProvider;
+import io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder;
import io.grpc.internal.SharedResourceHolder;
import io.grpc.internal.SharedResourceHolder.Resource;
import io.grpc.internal.TransportTracer;
@@ -54,10 +58,12 @@
/** Convenience class for building channels with the OkHttp transport. */
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1785")
-public class OkHttpChannelBuilder extends
- AbstractManagedChannelImplBuilder<OkHttpChannelBuilder> {
+public class OkHttpChannelBuilder extends ForwardingChannelBuilder<OkHttpChannelBuilder> {
public static final int DEFAULT_FLOW_CONTROL_WINDOW = 65535;
+ private final ManagedChannelImplBuilder managedChannelImplBuilder;
+ private TransportTracer.Factory transportTracerFactory = TransportTracer.getDefaultFactory();
+
/** Identifies the negotiation used for starting up HTTP/2. */
private enum NegotiationType {
@@ -127,6 +133,7 @@
private long keepAliveTimeoutNanos = DEFAULT_KEEPALIVE_TIMEOUT_NANOS;
private int flowControlWindow = DEFAULT_FLOW_CONTROL_WINDOW;
private boolean keepAliveWithoutCalls;
+ private int maxInboundMessageSize = GrpcUtil.DEFAULT_MAX_MESSAGE_SIZE;
private int maxInboundMetadataSize = Integer.MAX_VALUE;
/**
@@ -140,7 +147,29 @@
}
private OkHttpChannelBuilder(String target) {
- super(target);
+ final class OkHttpChannelTransportFactoryBuilder implements ClientTransportFactoryBuilder {
+ @Override
+ public ClientTransportFactory buildClientTransportFactory() {
+ return buildTransportFactory();
+ }
+ }
+
+ final class OkHttpChannelDefaultPortProvider implements ChannelBuilderDefaultPortProvider {
+ @Override
+ public int getDefaultPort() {
+ return OkHttpChannelBuilder.this.getDefaultPort();
+ }
+ }
+
+ managedChannelImplBuilder = new ManagedChannelImplBuilder(target,
+ new OkHttpChannelTransportFactoryBuilder(),
+ new OkHttpChannelDefaultPortProvider());
+ }
+
+ @Internal
+ @Override
+ protected final ManagedChannelBuilder<?> delegate() {
+ return managedChannelImplBuilder;
}
@VisibleForTesting
@@ -363,9 +392,19 @@
return this;
}
+ /**
+ * Sets the maximum message size allowed for a single gRPC frame. If an inbound messages
+ * larger than this limit is received it will not be processed and the RPC will fail with
+ * RESOURCE_EXHAUSTED.
+ */
@Override
- @Internal
- protected final ClientTransportFactory buildTransportFactory() {
+ public final OkHttpChannelBuilder maxInboundMessageSize(int max) {
+ Preconditions.checkArgument(max >= 0, "negative max");
+ maxInboundMessageSize = max;
+ return this;
+ }
+
+ final ClientTransportFactory buildTransportFactory() {
boolean enableKeepAlive = keepAliveTimeNanos != KEEPALIVE_TIME_NANOS_DISABLED;
return new OkHttpTransportFactory(
transportExecutor,
@@ -374,7 +413,7 @@
createSslSocketFactory(),
hostnameVerifier,
connectionSpec,
- maxInboundMessageSize(),
+ maxInboundMessageSize,
enableKeepAlive,
keepAliveTimeNanos,
keepAliveTimeoutNanos,
@@ -385,8 +424,17 @@
useGetForSafeMethods);
}
- @Override
- protected int getDefaultPort() {
+ final OkHttpChannelBuilder disableCheckAuthority() {
+ this.managedChannelImplBuilder.disableCheckAuthority();
+ return this;
+ }
+
+ final OkHttpChannelBuilder enableCheckAuthority() {
+ this.managedChannelImplBuilder.enableCheckAuthority();
+ return this;
+ }
+
+ final int getDefaultPort() {
switch (negotiationType) {
case PLAINTEXT:
return GrpcUtil.DEFAULT_PORT_PLAINTEXT;
@@ -397,6 +445,10 @@
}
}
+ final void setStatsEnabled(boolean value) {
+ this.managedChannelImplBuilder.setStatsEnabled(value);
+ }
+
@VisibleForTesting
@Nullable
SSLSocketFactory createSslSocketFactory() {
diff --git a/okhttp/src/test/java/io/grpc/okhttp/OkHttpChannelBuilderTest.java b/okhttp/src/test/java/io/grpc/okhttp/OkHttpChannelBuilderTest.java
index 512107e..4aa1d1a 100644
--- a/okhttp/src/test/java/io/grpc/okhttp/OkHttpChannelBuilderTest.java
+++ b/okhttp/src/test/java/io/grpc/okhttp/OkHttpChannelBuilderTest.java
@@ -72,20 +72,26 @@
}
@Test
- public void overrideAllowsInvalidAuthority() {
- OkHttpChannelBuilder builder = new OkHttpChannelBuilder("good", 1234) {
- @Override
- protected String checkAuthority(String authority) {
- return authority;
- }
- };
+ public void failOverrideInvalidAuthority() {
+ OkHttpChannelBuilder builder = new OkHttpChannelBuilder("good", 1234);
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Invalid authority:");
+ builder.overrideAuthority("[invalidauthority");
+ }
+
+ @Test
+ public void disableCheckAuthorityAllowsInvalidAuthority() {
+ OkHttpChannelBuilder builder = new OkHttpChannelBuilder("good", 1234)
+ .disableCheckAuthority();
builder.overrideAuthority("[invalidauthority").usePlaintext().buildTransportFactory();
}
@Test
- public void failOverrideInvalidAuthority() {
- OkHttpChannelBuilder builder = new OkHttpChannelBuilder("good", 1234);
+ public void enableCheckAuthorityFailOverrideInvalidAuthority() {
+ OkHttpChannelBuilder builder = new OkHttpChannelBuilder("good", 1234)
+ .disableCheckAuthority()
+ .enableCheckAuthority();
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Invalid authority:");