serviceConfig) {
+ delegate().defaultServiceConfig(serviceConfig);
+ return thisT();
+ }
+
+ @Override
+ public T disableServiceConfigLookUp() {
+ delegate().disableServiceConfigLookUp();
+ return thisT();
+ }
+
+ /**
+ * Returns the {@link ManagedChannel} built by the delegate by default. Overriding method can
+ * return different value.
+ */
+ @Override
+ public ManagedChannel build() {
+ return delegate().build();
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("delegate", delegate()).toString();
+ }
+
+ /**
+ * Returns the correctly typed version of the builder.
+ */
+ protected final T thisT() {
+ @SuppressWarnings("unchecked")
+ T thisT = (T) this;
+ return thisT;
+ }
+}
diff --git a/core/src/main/java/io/grpc/internal/AbstractServerImplBuilder.java b/core/src/main/java/io/grpc/internal/AbstractServerImplBuilder.java
new file mode 100644
index 00000000000..715161c0635
--- /dev/null
+++ b/core/src/main/java/io/grpc/internal/AbstractServerImplBuilder.java
@@ -0,0 +1,182 @@
+/*
+ * 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.internal;
+
+import com.google.common.base.MoreObjects;
+import io.grpc.BinaryLog;
+import io.grpc.BindableService;
+import io.grpc.CompressorRegistry;
+import io.grpc.DecompressorRegistry;
+import io.grpc.HandlerRegistry;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import io.grpc.ServerInterceptor;
+import io.grpc.ServerServiceDefinition;
+import io.grpc.ServerStreamTracer;
+import io.grpc.ServerTransportFilter;
+import java.io.File;
+import java.io.InputStream;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
+
+/**
+ * A {@link ServerBuilder} that delegates all its builder method to another builder by default.
+ *
+ * Temporarily duplicates io.grpc.ForwardingServerBuilder (temporarily package-private)
+ * to fix ABI backward compatibility.
+
+ * @param The concrete type of this builder.
+ * @see grpc/grpc-java#7211
+ */
+public abstract class AbstractServerImplBuilder
+ > extends ServerBuilder {
+
+ /** The default constructor. */
+ protected AbstractServerImplBuilder() {}
+
+ /**
+ * This method serves to force sub classes to "hide" this static factory.
+ */
+ public static ServerBuilder> forPort(int port) {
+ throw new UnsupportedOperationException("Subclass failed to hide static factory");
+ }
+
+ /**
+ * Returns the delegated {@code ServerBuilder}.
+ */
+ protected abstract ServerBuilder> delegate();
+
+ @Override
+ public T directExecutor() {
+ delegate().directExecutor();
+ return thisT();
+ }
+
+ @Override
+ public T executor(@Nullable Executor executor) {
+ delegate().executor(executor);
+ return thisT();
+ }
+
+ @Override
+ public T addService(ServerServiceDefinition service) {
+ delegate().addService(service);
+ return thisT();
+ }
+
+ @Override
+ public T addService(BindableService bindableService) {
+ delegate().addService(bindableService);
+ return thisT();
+ }
+
+ @Override
+ public T intercept(ServerInterceptor interceptor) {
+ delegate().intercept(interceptor);
+ return thisT();
+ }
+
+ @Override
+ public T addTransportFilter(ServerTransportFilter filter) {
+ delegate().addTransportFilter(filter);
+ return thisT();
+ }
+
+ @Override
+ public T addStreamTracerFactory(ServerStreamTracer.Factory factory) {
+ delegate().addStreamTracerFactory(factory);
+ return thisT();
+ }
+
+ @Override
+ public T fallbackHandlerRegistry(@Nullable HandlerRegistry fallbackRegistry) {
+ delegate().fallbackHandlerRegistry(fallbackRegistry);
+ return thisT();
+ }
+
+ @Override
+ public T useTransportSecurity(File certChain, File privateKey) {
+ delegate().useTransportSecurity(certChain, privateKey);
+ return thisT();
+ }
+
+ @Override
+ public T useTransportSecurity(InputStream certChain, InputStream privateKey) {
+ delegate().useTransportSecurity(certChain, privateKey);
+ return thisT();
+ }
+
+ @Override
+ public T decompressorRegistry(@Nullable DecompressorRegistry registry) {
+ delegate().decompressorRegistry(registry);
+ return thisT();
+ }
+
+ @Override
+ public T compressorRegistry(@Nullable CompressorRegistry registry) {
+ delegate().compressorRegistry(registry);
+ return thisT();
+ }
+
+ @Override
+ public T handshakeTimeout(long timeout, TimeUnit unit) {
+ delegate().handshakeTimeout(timeout, unit);
+ return thisT();
+ }
+
+ @Override
+ public T maxInboundMessageSize(int bytes) {
+ delegate().maxInboundMessageSize(bytes);
+ return thisT();
+ }
+
+ @Override
+ public T maxInboundMetadataSize(int bytes) {
+ delegate().maxInboundMetadataSize(bytes);
+ return thisT();
+ }
+
+ @Override
+ public T setBinaryLog(BinaryLog binaryLog) {
+ delegate().setBinaryLog(binaryLog);
+ return thisT();
+ }
+
+ /**
+ * Returns the {@link Server} built by the delegate by default. Overriding method can return
+ * different value.
+ */
+ @Override
+ public Server build() {
+ return delegate().build();
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("delegate", delegate()).toString();
+ }
+
+ /**
+ * Returns the correctly typed version of the builder.
+ */
+ protected final T thisT() {
+ @SuppressWarnings("unchecked")
+ T thisT = (T) this;
+ return thisT;
+ }
+}
diff --git a/core/src/main/java/io/grpc/internal/ClientCallImpl.java b/core/src/main/java/io/grpc/internal/ClientCallImpl.java
index 3c3a2227780..86ec0575adf 100644
--- a/core/src/main/java/io/grpc/internal/ClientCallImpl.java
+++ b/core/src/main/java/io/grpc/internal/ClientCallImpl.java
@@ -54,6 +54,7 @@
import io.perfmark.Tag;
import java.io.InputStream;
import java.nio.charset.Charset;
+import java.util.Locale;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
@@ -441,7 +442,7 @@ public void run() {
buf.append('-');
}
buf.append(seconds);
- buf.append(String.format(".%09d", nanos));
+ buf.append(String.format(Locale.US, ".%09d", nanos));
buf.append("s. ");
buf.append(insight);
stream.cancel(DEADLINE_EXCEEDED.augmentDescription(buf.toString()));
diff --git a/core/src/main/java/io/grpc/internal/DelayedClientCall.java b/core/src/main/java/io/grpc/internal/DelayedClientCall.java
index c3d3823ed11..41f672af347 100644
--- a/core/src/main/java/io/grpc/internal/DelayedClientCall.java
+++ b/core/src/main/java/io/grpc/internal/DelayedClientCall.java
@@ -30,6 +30,7 @@
import io.grpc.Status;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@@ -117,7 +118,7 @@ private ScheduledFuture> scheduleDeadlineIfNeeded(
buf.append("Deadline exceeded after ");
}
buf.append(seconds);
- buf.append(String.format(".%09d", nanos));
+ buf.append(String.format(Locale.US, ".%09d", nanos));
buf.append("s. ");
/** Cancels the call if deadline exceeded prior to the real call being set. */
class DeadlineExceededRunnable implements Runnable {
diff --git a/core/src/main/java/io/grpc/internal/GrpcUtil.java b/core/src/main/java/io/grpc/internal/GrpcUtil.java
index ce46d8c9bf5..2a51fd165e8 100644
--- a/core/src/main/java/io/grpc/internal/GrpcUtil.java
+++ b/core/src/main/java/io/grpc/internal/GrpcUtil.java
@@ -197,7 +197,7 @@ public byte[] parseAsciiString(byte[] serialized) {
public static final Splitter ACCEPT_ENCODING_SPLITTER = Splitter.on(',').trimResults();
- private static final String IMPLEMENTATION_VERSION = "1.33.0"; // CURRENT_GRPC_VERSION
+ private static final String IMPLEMENTATION_VERSION = "1.33.1"; // CURRENT_GRPC_VERSION
/**
* The default timeout in nanos for a keepalive ping request.
diff --git a/core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java b/core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java
new file mode 100644
index 00000000000..8643165eec6
--- /dev/null
+++ b/core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.internal;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.base.Defaults;
+import io.grpc.ForwardingTestUtil;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Unit tests for {@link AbstractManagedChannelImplBuilder}.
+ */
+@RunWith(JUnit4.class)
+public class AbstractManagedChannelImplBuilderTest {
+ private final ManagedChannelBuilder> mockDelegate = mock(ManagedChannelBuilder.class);
+
+ private final AbstractManagedChannelImplBuilder> testChannelBuilder = new TestBuilder();
+
+ private final class TestBuilder extends AbstractManagedChannelImplBuilder {
+ @Override
+ protected ManagedChannelBuilder> delegate() {
+ return mockDelegate;
+ }
+ }
+
+ @Test
+ public void allMethodsForwarded() throws Exception {
+ ForwardingTestUtil.testMethodsForwarded(
+ ManagedChannelBuilder.class,
+ mockDelegate,
+ testChannelBuilder,
+ Collections.emptyList(),
+ new ForwardingTestUtil.ArgumentProvider() {
+ @Override
+ public Object get(Method method, int argPos, Class> clazz) {
+ if (method.getName().equals("maxInboundMetadataSize")) {
+ assertThat(argPos).isEqualTo(0);
+ return 1; // an arbitrary positive number
+ }
+ return null;
+ }
+ });
+ }
+
+ @Test
+ public void allBuilderMethodsReturnThis() throws Exception {
+ for (Method method : ManagedChannelBuilder.class.getDeclaredMethods()) {
+ if (Modifier.isStatic(method.getModifiers()) || Modifier.isPrivate(method.getModifiers())) {
+ continue;
+ }
+ if (method.getName().equals("build")) {
+ continue;
+ }
+ Class>[] argTypes = method.getParameterTypes();
+ Object[] args = new Object[argTypes.length];
+ for (int i = 0; i < argTypes.length; i++) {
+ args[i] = Defaults.defaultValue(argTypes[i]);
+ }
+ if (method.getName().equals("maxInboundMetadataSize")) {
+ args[0] = 1; // an arbitrary positive number
+ }
+
+ Object returnedValue = method.invoke(testChannelBuilder, args);
+
+ assertThat(returnedValue).isSameInstanceAs(testChannelBuilder);
+ }
+ }
+
+ @Test
+ public void buildReturnsDelegateBuildByDefault() {
+ ManagedChannel mockChannel = mock(ManagedChannel.class);
+ doReturn(mockChannel).when(mockDelegate).build();
+
+ assertThat(testChannelBuilder.build()).isSameInstanceAs(mockChannel);
+ }
+}
diff --git a/core/src/test/java/io/grpc/internal/AbstractServerImplBuilderTest.java b/core/src/test/java/io/grpc/internal/AbstractServerImplBuilderTest.java
new file mode 100644
index 00000000000..9f6859a8420
--- /dev/null
+++ b/core/src/test/java/io/grpc/internal/AbstractServerImplBuilderTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.internal;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.base.Defaults;
+import io.grpc.ForwardingTestUtil;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Unit tests for {@link AbstractServerImplBuilderTest}.
+ */
+@RunWith(JUnit4.class)
+public class AbstractServerImplBuilderTest {
+ private final ServerBuilder> mockDelegate = mock(ServerBuilder.class);
+
+ private final AbstractServerImplBuilder> testServerBuilder = new TestBuilder();
+
+ private final class TestBuilder extends AbstractServerImplBuilder {
+ @Override
+ protected ServerBuilder> delegate() {
+ return mockDelegate;
+ }
+ }
+
+ @Test
+ public void allMethodsForwarded() throws Exception {
+ ForwardingTestUtil.testMethodsForwarded(
+ ServerBuilder.class,
+ mockDelegate,
+ testServerBuilder,
+ Collections.emptyList());
+ }
+
+ @Test
+ public void allBuilderMethodsReturnThis() throws Exception {
+ for (Method method : ServerBuilder.class.getDeclaredMethods()) {
+ if (Modifier.isStatic(method.getModifiers()) || Modifier.isPrivate(method.getModifiers())) {
+ continue;
+ }
+ if (method.getName().equals("build")) {
+ continue;
+ }
+ Class>[] argTypes = method.getParameterTypes();
+ Object[] args = new Object[argTypes.length];
+ for (int i = 0; i < argTypes.length; i++) {
+ args[i] = Defaults.defaultValue(argTypes[i]);
+ }
+
+ Object returnedValue = method.invoke(testServerBuilder, args);
+
+ assertThat(returnedValue).isSameInstanceAs(testServerBuilder);
+ }
+ }
+
+ @Test
+ public void buildReturnsDelegateBuildByDefault() {
+ Server server = mock(Server.class);
+ doReturn(server).when(mockDelegate).build();
+
+ assertThat(testServerBuilder.build()).isSameInstanceAs(server);
+ }
+}
diff --git a/cronet/README.md b/cronet/README.md
index 530fbea71b0..9132af622c4 100644
--- a/cronet/README.md
+++ b/cronet/README.md
@@ -26,7 +26,7 @@ In your app module's `build.gradle` file, include a dependency on both `grpc-cro
Google Play Services Client Library for Cronet
```
-implementation 'io.grpc:grpc-cronet:1.33.0'
+implementation 'io.grpc:grpc-cronet:1.33.1'
implementation 'com.google.android.gms:play-services-cronet:16.0.0'
```
diff --git a/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java b/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java
index 3ed71e234aa..68182421333 100644
--- a/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java
+++ b/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java
@@ -26,9 +26,9 @@
import com.google.common.util.concurrent.MoreExecutors;
import io.grpc.ChannelLogger;
import io.grpc.ExperimentalApi;
-import io.grpc.ForwardingChannelBuilder;
import io.grpc.Internal;
import io.grpc.ManagedChannelBuilder;
+import io.grpc.internal.AbstractManagedChannelImplBuilder;
import io.grpc.internal.ClientTransportFactory;
import io.grpc.internal.ConnectionClientTransport;
import io.grpc.internal.GrpcUtil;
@@ -50,7 +50,8 @@
/** Convenience class for building channels with the cronet transport. */
@ExperimentalApi("There is no plan to make this API stable, given transport API instability")
-public final class CronetChannelBuilder extends ForwardingChannelBuilder {
+public final class CronetChannelBuilder
+ extends AbstractManagedChannelImplBuilder {
private static final String LOG_TAG = "CronetChannelBuilder";
diff --git a/documentation/android-channel-builder.md b/documentation/android-channel-builder.md
index b152c9286a0..a84d9a32652 100644
--- a/documentation/android-channel-builder.md
+++ b/documentation/android-channel-builder.md
@@ -36,8 +36,8 @@ In your `build.gradle` file, include a dependency on both `grpc-android` and
`grpc-okhttp`:
```
-implementation 'io.grpc:grpc-android:1.33.0'
-implementation 'io.grpc:grpc-okhttp:1.33.0'
+implementation 'io.grpc:grpc-android:1.33.1'
+implementation 'io.grpc:grpc-okhttp:1.33.1'
```
You also need permission to access the device's network state in your
diff --git a/examples/android/clientcache/app/build.gradle b/examples/android/clientcache/app/build.gradle
index 6ae625419a6..c972b4df3f3 100644
--- a/examples/android/clientcache/app/build.gradle
+++ b/examples/android/clientcache/app/build.gradle
@@ -30,7 +30,7 @@ android {
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.12.0' }
plugins {
- grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.0' // CURRENT_GRPC_VERSION
+ grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.1' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
@@ -50,12 +50,12 @@ dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
// You need to build grpc-java to obtain these libraries below.
- implementation 'io.grpc:grpc-okhttp:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-protobuf-lite:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-stub:1.33.0' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-okhttp:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-protobuf-lite:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-stub:1.33.1' // CURRENT_GRPC_VERSION
implementation 'org.apache.tomcat:annotations-api:6.0.53'
testImplementation 'junit:junit:4.12'
testImplementation 'com.google.truth:truth:1.0.1'
- testImplementation 'io.grpc:grpc-testing:1.33.0' // CURRENT_GRPC_VERSION
+ testImplementation 'io.grpc:grpc-testing:1.33.1' // CURRENT_GRPC_VERSION
}
diff --git a/examples/android/helloworld/app/build.gradle b/examples/android/helloworld/app/build.gradle
index 5211c63b6c1..20cb76bc97d 100644
--- a/examples/android/helloworld/app/build.gradle
+++ b/examples/android/helloworld/app/build.gradle
@@ -28,7 +28,7 @@ android {
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.12.0' }
plugins {
- grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.0' // CURRENT_GRPC_VERSION
+ grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.1' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
@@ -48,8 +48,8 @@ dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
// You need to build grpc-java to obtain these libraries below.
- implementation 'io.grpc:grpc-okhttp:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-protobuf-lite:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-stub:1.33.0' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-okhttp:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-protobuf-lite:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-stub:1.33.1' // CURRENT_GRPC_VERSION
implementation 'org.apache.tomcat:annotations-api:6.0.53'
}
diff --git a/examples/android/routeguide/app/build.gradle b/examples/android/routeguide/app/build.gradle
index c0621d62bc4..f4e814f873f 100644
--- a/examples/android/routeguide/app/build.gradle
+++ b/examples/android/routeguide/app/build.gradle
@@ -28,7 +28,7 @@ android {
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.12.0' }
plugins {
- grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.0' // CURRENT_GRPC_VERSION
+ grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.1' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
@@ -48,8 +48,8 @@ dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
// You need to build grpc-java to obtain these libraries below.
- implementation 'io.grpc:grpc-okhttp:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-protobuf-lite:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-stub:1.33.0' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-okhttp:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-protobuf-lite:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-stub:1.33.1' // CURRENT_GRPC_VERSION
implementation 'org.apache.tomcat:annotations-api:6.0.53'
}
diff --git a/examples/android/strictmode/app/build.gradle b/examples/android/strictmode/app/build.gradle
index 7dee456fb1f..2ce7202745d 100644
--- a/examples/android/strictmode/app/build.gradle
+++ b/examples/android/strictmode/app/build.gradle
@@ -29,7 +29,7 @@ android {
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.12.0' }
plugins {
- grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.0' // CURRENT_GRPC_VERSION
+ grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.33.1' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
@@ -49,8 +49,8 @@ dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
// You need to build grpc-java to obtain these libraries below.
- implementation 'io.grpc:grpc-okhttp:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-protobuf-lite:1.33.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-stub:1.33.0' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-okhttp:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-protobuf-lite:1.33.1' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-stub:1.33.1' // CURRENT_GRPC_VERSION
implementation 'org.apache.tomcat:annotations-api:6.0.53'
}
diff --git a/examples/build.gradle b/examples/build.gradle
index 4b6c733151e..bc976de708a 100644
--- a/examples/build.gradle
+++ b/examples/build.gradle
@@ -22,7 +22,7 @@ targetCompatibility = 1.7
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
-def grpcVersion = '1.33.0' // CURRENT_GRPC_VERSION
+def grpcVersion = '1.33.1' // CURRENT_GRPC_VERSION
def protobufVersion = '3.12.0'
def protocVersion = protobufVersion
diff --git a/examples/example-alts/build.gradle b/examples/example-alts/build.gradle
index e01598187f3..3fde646e060 100644
--- a/examples/example-alts/build.gradle
+++ b/examples/example-alts/build.gradle
@@ -23,7 +23,7 @@ targetCompatibility = 1.7
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
-def grpcVersion = '1.33.0' // CURRENT_GRPC_VERSION
+def grpcVersion = '1.33.1' // CURRENT_GRPC_VERSION
def protocVersion = '3.12.0'
dependencies {
diff --git a/examples/example-gauth/build.gradle b/examples/example-gauth/build.gradle
index 6542df94351..9037f82987e 100644
--- a/examples/example-gauth/build.gradle
+++ b/examples/example-gauth/build.gradle
@@ -23,7 +23,7 @@ targetCompatibility = 1.7
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
-def grpcVersion = '1.33.0' // CURRENT_GRPC_VERSION
+def grpcVersion = '1.33.1' // CURRENT_GRPC_VERSION
def protobufVersion = '3.12.0'
def protocVersion = protobufVersion
diff --git a/examples/example-gauth/pom.xml b/examples/example-gauth/pom.xml
index a255df8a0dd..dd1a08fee8a 100644
--- a/examples/example-gauth/pom.xml
+++ b/examples/example-gauth/pom.xml
@@ -6,13 +6,13 @@
jar
- 1.33.0
+ 1.33.1
example-gauth
https://github.com/grpc/grpc-java
UTF-8
- 1.33.0
+ 1.33.1
3.12.0
1.7
diff --git a/examples/example-hostname/build.gradle b/examples/example-hostname/build.gradle
index f7f44ab430e..d621bb5201e 100644
--- a/examples/example-hostname/build.gradle
+++ b/examples/example-hostname/build.gradle
@@ -21,7 +21,7 @@ targetCompatibility = 1.7
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
-def grpcVersion = '1.33.0' // CURRENT_GRPC_VERSION
+def grpcVersion = '1.33.1' // CURRENT_GRPC_VERSION
def protobufVersion = '3.12.0'
dependencies {
diff --git a/examples/example-hostname/pom.xml b/examples/example-hostname/pom.xml
index a01948f90ce..b5ec5a12681 100644
--- a/examples/example-hostname/pom.xml
+++ b/examples/example-hostname/pom.xml
@@ -6,13 +6,13 @@
jar
- 1.33.0
+ 1.33.1
example-hostname
https://github.com/grpc/grpc-java
UTF-8
- 1.33.0
+ 1.33.1
3.12.0
1.7
diff --git a/examples/example-jwt-auth/build.gradle b/examples/example-jwt-auth/build.gradle
index d827dcdf017..1ec1d0bef61 100644
--- a/examples/example-jwt-auth/build.gradle
+++ b/examples/example-jwt-auth/build.gradle
@@ -22,7 +22,7 @@ targetCompatibility = 1.7
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
-def grpcVersion = '1.33.0' // CURRENT_GRPC_VERSION
+def grpcVersion = '1.33.1' // CURRENT_GRPC_VERSION
def protobufVersion = '3.12.0'
def protocVersion = protobufVersion
diff --git a/examples/example-jwt-auth/pom.xml b/examples/example-jwt-auth/pom.xml
index c6064be0a00..c6d1d62d2ba 100644
--- a/examples/example-jwt-auth/pom.xml
+++ b/examples/example-jwt-auth/pom.xml
@@ -7,13 +7,13 @@
jar
- 1.33.0
+ 1.33.1
example-jwt-auth
https://github.com/grpc/grpc-java
UTF-8
- 1.33.0
+ 1.33.1
3.12.0
3.12.0
diff --git a/examples/example-tls/build.gradle b/examples/example-tls/build.gradle
index 1fb5859bdca..75a22fab856 100644
--- a/examples/example-tls/build.gradle
+++ b/examples/example-tls/build.gradle
@@ -23,7 +23,7 @@ targetCompatibility = 1.7
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
-def grpcVersion = '1.33.0' // CURRENT_GRPC_VERSION
+def grpcVersion = '1.33.1' // CURRENT_GRPC_VERSION
def nettyTcNativeVersion = '2.0.31.Final'
def protocVersion = '3.12.0'
diff --git a/examples/example-tls/pom.xml b/examples/example-tls/pom.xml
index 08f948edf94..e223fbfb162 100644
--- a/examples/example-tls/pom.xml
+++ b/examples/example-tls/pom.xml
@@ -6,13 +6,13 @@
jar
- 1.33.0
+ 1.33.1
example-tls
https://github.com/grpc/grpc-java
UTF-8
- 1.33.0
+ 1.33.1
3.12.0
2.0.31.Final
diff --git a/examples/example-xds/build.gradle b/examples/example-xds/build.gradle
index ccb3a68803c..54484e22023 100644
--- a/examples/example-xds/build.gradle
+++ b/examples/example-xds/build.gradle
@@ -18,7 +18,7 @@ targetCompatibility = 1.7
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
-def grpcVersion = '1.33.0' // CURRENT_GRPC_VERSION
+def grpcVersion = '1.33.1' // CURRENT_GRPC_VERSION
dependencies {
// This example's client is the same as the helloworld client. We depend on the helloworld
diff --git a/examples/pom.xml b/examples/pom.xml
index e7d66e501c6..2fc62b0e8e4 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -6,13 +6,13 @@
jar
- 1.33.0
+ 1.33.1
examples
https://github.com/grpc/grpc-java
UTF-8
- 1.33.0
+ 1.33.1
3.12.0
3.12.0
diff --git a/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java b/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java
index 9757cbb3f98..4b5de5963f8 100644
--- a/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java
+++ b/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java
@@ -28,10 +28,10 @@
import io.grpc.ChannelLogger;
import io.grpc.EquivalentAddressGroup;
import io.grpc.ExperimentalApi;
-import io.grpc.ForwardingChannelBuilder;
import io.grpc.HttpConnectProxiedSocketAddress;
import io.grpc.Internal;
import io.grpc.ManagedChannelBuilder;
+import io.grpc.internal.AbstractManagedChannelImplBuilder;
import io.grpc.internal.AtomicBackoff;
import io.grpc.internal.ClientTransportFactory;
import io.grpc.internal.ConnectionClientTransport;
@@ -67,7 +67,8 @@
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1784")
@CanIgnoreReturnValue
-public final class NettyChannelBuilder extends ForwardingChannelBuilder {
+public final class NettyChannelBuilder extends
+ AbstractManagedChannelImplBuilder {
// 1MiB.
public static final int DEFAULT_FLOW_CONTROL_WINDOW = 1024 * 1024;
diff --git a/netty/src/main/java/io/grpc/netty/NettyClientHandler.java b/netty/src/main/java/io/grpc/netty/NettyClientHandler.java
index 61052bd190c..631d9e81863 100644
--- a/netty/src/main/java/io/grpc/netty/NettyClientHandler.java
+++ b/netty/src/main/java/io/grpc/netty/NettyClientHandler.java
@@ -129,6 +129,7 @@ protected void handleNotInUse() {
private Http2Ping ping;
private Attributes attributes;
private InternalChannelz.Security securityInfo;
+ private Status abruptGoAwayStatus;
static NettyClientHandler newHandler(
ClientTransportLifecycleManager lifecycleManager,
@@ -556,6 +557,21 @@ private void createStream(CreateStreamCommand command, ChannelPromise promise)
}
return;
}
+ if (connection().goAwayReceived()
+ && streamId > connection().local().lastStreamKnownByPeer()) {
+ // This should only be reachable during onGoAwayReceived, as otherwise
+ // getShutdownThrowable() != null
+ command.stream().setNonExistent();
+ Status s = abruptGoAwayStatus;
+ if (s == null) {
+ // Should be impossible, but handle psuedo-gracefully
+ s = Status.INTERNAL.withDescription(
+ "Failed due to abrupt GOAWAY, but can't find GOAWAY details");
+ }
+ command.stream().transportReportStatus(s, RpcProgress.REFUSED, true, new Metadata());
+ promise.setFailure(s.asRuntimeException());
+ return;
+ }
NettyClientStream.TransportState stream = command.stream();
Http2Headers headers = command.headers();
@@ -772,6 +788,7 @@ public boolean visit(Http2Stream stream) throws Http2Exception {
*/
private void goingAway(Status status) {
lifecycleManager.notifyGracefulShutdown(status);
+ abruptGoAwayStatus = status;
// Try to allocate as many in-flight streams as possible, to reduce race window of
// https://github.com/grpc/grpc-java/issues/2562 . To be of any help, the server has to
// gracefully shut down the connection with two GOAWAYs. gRPC servers generally send a PING
diff --git a/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java b/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java
index 8bda3d7c91e..520e3bfbd9a 100644
--- a/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java
+++ b/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java
@@ -27,10 +27,10 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.grpc.ExperimentalApi;
-import io.grpc.ForwardingServerBuilder;
import io.grpc.Internal;
import io.grpc.ServerBuilder;
import io.grpc.ServerStreamTracer;
+import io.grpc.internal.AbstractServerImplBuilder;
import io.grpc.internal.FixedObjectPool;
import io.grpc.internal.GrpcUtil;
import io.grpc.internal.InternalServer;
@@ -66,7 +66,7 @@
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1784")
@CanIgnoreReturnValue
-public final class NettyServerBuilder extends ForwardingServerBuilder {
+public final class NettyServerBuilder extends AbstractServerImplBuilder {
// 1MiB
public static final int DEFAULT_FLOW_CONTROL_WINDOW = 1024 * 1024;
diff --git a/netty/src/test/java/io/grpc/netty/NettyClientHandlerTest.java b/netty/src/test/java/io/grpc/netty/NettyClientHandlerTest.java
index 0ff2d981410..4e469e707bf 100644
--- a/netty/src/test/java/io/grpc/netty/NettyClientHandlerTest.java
+++ b/netty/src/test/java/io/grpc/netty/NettyClientHandlerTest.java
@@ -375,6 +375,23 @@ public void receivedGoAwayShouldNotAffectRacingQueuedStreamId() throws Exception
assertTrue(future.isDone());
}
+ @Test
+ public void receivedAbruptGoAwayShouldFailRacingQueuedStreamid() throws Exception {
+ // This command has not actually been executed yet
+ ChannelFuture future = writeQueue().enqueue(
+ newCreateStreamCommand(grpcHeaders, streamTransportState), true);
+ // Read a GOAWAY that indicates our stream can't be sent
+ channelRead(goAwayFrame(0, 8 /* Cancel */, Unpooled.copiedBuffer("this is a test", UTF_8)));
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(Status.class);
+ verify(streamListener).closed(captor.capture(), same(REFUSED),
+ ArgumentMatchers.notNull());
+ assertEquals(Status.CANCELLED.getCode(), captor.getValue().getCode());
+ assertEquals("HTTP/2 error code: CANCEL\nReceived Goaway\nthis is a test",
+ captor.getValue().getDescription());
+ assertTrue(future.isDone());
+ }
+
@Test
public void receivedResetWithRefuseCode() throws Exception {
ChannelFuture future = enqueue(newCreateStreamCommand(grpcHeaders, streamTransportState));
diff --git a/okhttp/build.gradle b/okhttp/build.gradle
index 0c23c3b9f80..5b2f1a13e35 100644
--- a/okhttp/build.gradle
+++ b/okhttp/build.gradle
@@ -34,8 +34,11 @@ project.sourceSets {
checkstyleMain.exclude '**/io/grpc/okhttp/internal/**'
-javadoc.exclude 'io/grpc/okhttp/internal/**'
-javadoc.options.links 'http://square.github.io/okhttp/2.x/okhttp/'
+javadoc {
+ options.links 'http://square.github.io/okhttp/2.x/okhttp/'
+ exclude 'io/grpc/okhttp/Internal*'
+ exclude 'io/grpc/okhttp/internal/**'
+}
jacocoTestReport {
classDirectories.from = sourceSets.main.output.collect {
diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
index 93ea57e2df4..05cb2fea8be 100644
--- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
+++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
@@ -24,9 +24,9 @@
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.ManagedChannelBuilder;
+import io.grpc.internal.AbstractManagedChannelImplBuilder;
import io.grpc.internal.AtomicBackoff;
import io.grpc.internal.ClientTransportFactory;
import io.grpc.internal.ConnectionClientTransport;
@@ -58,7 +58,8 @@
/** Convenience class for building channels with the OkHttp transport. */
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1785")
-public final class OkHttpChannelBuilder extends ForwardingChannelBuilder {
+public final class OkHttpChannelBuilder extends
+ AbstractManagedChannelImplBuilder {
public static final int DEFAULT_FLOW_CONTROL_WINDOW = 65535;
private final ManagedChannelImplBuilder managedChannelImplBuilder;