diff --git a/core/src/main/java/io/grpc/inprocess/InProcessTransport.java b/core/src/main/java/io/grpc/inprocess/InProcessTransport.java index 2169a5bb2d..6d1b8c8047 100644 --- a/core/src/main/java/io/grpc/inprocess/InProcessTransport.java +++ b/core/src/main/java/io/grpc/inprocess/InProcessTransport.java @@ -164,6 +164,11 @@ class InProcessTransport implements ServerTransport, ClientTransport { } } + @Override + public String toString() { + return getClass().getSimpleName() + "(" + name + ")"; + } + private synchronized void notifyShutdown(Status s) { if (shutdown) { return; diff --git a/core/src/main/java/io/grpc/internal/ClientCallImpl.java b/core/src/main/java/io/grpc/internal/ClientCallImpl.java index 5f8e3b3e17..6ad6eaee9c 100644 --- a/core/src/main/java/io/grpc/internal/ClientCallImpl.java +++ b/core/src/main/java/io/grpc/internal/ClientCallImpl.java @@ -434,7 +434,14 @@ final class ClientCallImpl extends ClientCall trailers = new Metadata(); } } - final Status savedStatus = status; + ClientTransport transport = null; + try { + transport = transportFuture.get(); + } catch (Exception e) { + // Ignore the exception, and keep transport as null. + } + final Status savedStatus = (transport == null + ? status : status.augmentDescription("transport=" + transport)); final Metadata savedTrailers = trailers; callExecutor.execute(new ContextRunnable(context) { @Override diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java index 0a5e539265..b19683a179 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java @@ -158,8 +158,7 @@ public class ManagedChannelImplTest { ClientCall call = channel.newCall(method, CallOptions.DEFAULT.withDeadlineNanoTime(System.nanoTime())); call.start(mockCallListener, new Metadata()); - verify(mockCallListener, timeout(1000)).onClose( - same(Status.DEADLINE_EXCEEDED), any(Metadata.class)); + verifyListenerClosed(mockCallListener, Status.Code.DEADLINE_EXCEEDED); } @Test @@ -211,7 +210,7 @@ public class ManagedChannelImplTest { ClientStreamListener streamListener2 = streamListenerCaptor.getValue(); Metadata trailers = new Metadata(); streamListener2.closed(Status.CANCELLED, trailers); - verify(mockCallListener2, timeout(1000)).onClose(Status.CANCELLED, trailers); + verifyListenerClosed(mockCallListener2, Status.Code.CANCELLED); // Shutdown channel.shutdown(); @@ -235,7 +234,7 @@ public class ManagedChannelImplTest { transportListener.transportShutdown(Status.CANCELLED); assertFalse(channel.isTerminated()); streamListener.closed(Status.CANCELLED, trailers); - verify(mockCallListener, timeout(1000)).onClose(Status.CANCELLED, trailers); + verifyListenerClosed(mockCallListener, Status.Code.CANCELLED); assertFalse(channel.isTerminated()); transportListener.transportTerminated(); @@ -385,7 +384,7 @@ public class ManagedChannelImplTest { call.start(mockCallListener, headers); ArgumentCaptor badTransportListenerCaptor = ArgumentCaptor.forClass(ClientTransport.Listener.class); - verify(mockCallListener, timeout(1000)).onClose(same(Status.UNAVAILABLE), any(Metadata.class)); + verifyListenerClosed(mockCallListener, Status.Code.UNAVAILABLE); verify(badTransport, timeout(1000)).start(badTransportListenerCaptor.capture()); badTransportListenerCaptor.getValue().transportShutdown(Status.UNAVAILABLE); @@ -396,6 +395,14 @@ public class ManagedChannelImplTest { same(method), same(headers), any(ClientStreamListener.class)); } + private void verifyListenerClosed(ClientCall.Listener mockCallListener, + Status.Code statusCode) { + ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Status.class); + verify(mockCallListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class)); + Status status = statusCaptor.getValue(); + assertEquals(statusCode, status.getCode()); + } + private static class FakeBackoffPolicyProvider implements BackoffPolicy.Provider { @Override public BackoffPolicy get() { diff --git a/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer.java b/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer.java index cbbdf658c9..56c24dd072 100644 --- a/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer.java +++ b/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer.java @@ -358,6 +358,7 @@ class GrpclbLoadBalancer extends LoadBalancer { if (lbResponseObserver != this) { return; } + logger.info("Received " + status + ", entering fallback mode"); directTransport = transportFuture = Futures.immediateFuture(lbTransport); pendingPicksFulfillmentBatch = pendingPicks.createFulfillmentBatch(); } diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractTransportTest.java b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractTransportTest.java index 43d08c57a3..5ec6e238ec 100644 --- a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractTransportTest.java +++ b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractTransportTest.java @@ -338,7 +338,8 @@ public abstract class AbstractTransportTest { requestObserver.onError(new RuntimeException()); responseObserver.awaitCompletion(); assertEquals(Arrays.asList(), responseObserver.getValues()); - assertEquals(Status.CANCELLED, Status.fromThrowable(responseObserver.getError())); + assertEquals(Status.Code.CANCELLED, + Status.fromThrowable(responseObserver.getError()).getCode()); } @Test(timeout = 10000) @@ -366,7 +367,7 @@ public abstract class AbstractTransportTest { requestObserver.onError(new RuntimeException()); ArgumentCaptor captor = ArgumentCaptor.forClass(Throwable.class); verify(responseObserver, timeout(OPERATION_TIMEOUT)).onError(captor.capture()); - assertEquals(Status.CANCELLED, Status.fromThrowable(captor.getValue())); + assertEquals(Status.Code.CANCELLED, Status.fromThrowable(captor.getValue()).getCode()); verifyNoMoreInteractions(responseObserver); } @@ -489,7 +490,8 @@ public abstract class AbstractTransportTest { // Make sure that everything still completes. call.request(1); assertEquals(goldenResponses.get(1), queue.poll(OPERATION_TIMEOUT, TimeUnit.MILLISECONDS)); - assertEquals(Status.OK, queue.poll(OPERATION_TIMEOUT, TimeUnit.MILLISECONDS)); + assertEquals(Status.Code.OK, + ((Status) queue.poll(OPERATION_TIMEOUT, TimeUnit.MILLISECONDS)).getCode()); } @Test(timeout = 30000) @@ -632,7 +634,7 @@ public abstract class AbstractTransportTest { .build()).next(); fail("Expected deadline to be exceeded"); } catch (Throwable t) { - assertEquals(Status.DEADLINE_EXCEEDED, Status.fromThrowable(t)); + assertEquals(Status.Code.DEADLINE_EXCEEDED, Status.fromThrowable(t).getCode()); } } @@ -655,7 +657,8 @@ public abstract class AbstractTransportTest { .withDeadlineAfter(30, TimeUnit.MILLISECONDS) .streamingOutputCall(request, recorder); recorder.awaitCompletion(); - assertEquals(Status.DEADLINE_EXCEEDED, Status.fromThrowable(recorder.getError())); + assertEquals(Status.Code.DEADLINE_EXCEEDED, + Status.fromThrowable(recorder.getError()).getCode()); } protected int unaryPayloadLength() { diff --git a/netty/src/main/java/io/grpc/netty/NettyClientTransport.java b/netty/src/main/java/io/grpc/netty/NettyClientTransport.java index 49fbf10300..e74084d9aa 100644 --- a/netty/src/main/java/io/grpc/netty/NettyClientTransport.java +++ b/netty/src/main/java/io/grpc/netty/NettyClientTransport.java @@ -212,6 +212,11 @@ class NettyClientTransport implements ClientTransport { } } + @Override + public String toString() { + return getClass().getSimpleName() + "(" + address + ")"; + } + private void notifyShutdown(Status status) { Preconditions.checkNotNull(status, "status"); boolean notifyShutdown; diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java index 8ba03fc5e3..f5f64e6831 100644 --- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java +++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java @@ -404,6 +404,11 @@ class OkHttpClientTransport implements ClientTransport { }); } + @Override + public String toString() { + return getClass().getSimpleName() + "(" + address + ")"; + } + /** * Gets the overriden authority hostname. If the authority is overriden to be an invalid * authority, uri.getHost() will (rightly) return null, since the authority is no longer