diff --git a/core/src/main/java/io/grpc/inprocess/InProcessTransport.java b/core/src/main/java/io/grpc/inprocess/InProcessTransport.java index 18093946de..7350de4f1f 100644 --- a/core/src/main/java/io/grpc/inprocess/InProcessTransport.java +++ b/core/src/main/java/io/grpc/inprocess/InProcessTransport.java @@ -122,6 +122,8 @@ final class InProcessTransport implements ServerTransport, ConnectionClientTrans this.attributes = Attributes.newBuilder() .set(GrpcAttributes.ATTR_SECURITY_LEVEL, SecurityLevel.PRIVACY_AND_INTEGRITY) .set(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS, eagAttrs) + .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, new InProcessSocketAddress(name)) + .set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, new InProcessSocketAddress(name)) .build(); logId = InternalLogId.allocate(getClass(), name); } @@ -783,7 +785,7 @@ final class InProcessTransport implements ServerTransport, ConnectionClientTrans @Override public Attributes getAttributes() { - return Attributes.EMPTY; + return attributes; } @Override diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java index 770e1be419..65274cad70 100644 --- a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java +++ b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java @@ -153,6 +153,8 @@ public abstract class AbstractInteropTest { private final AtomicReference> serverCallCapture = new AtomicReference<>(); + private final AtomicReference> clientCallCapture = + new AtomicReference<>(); private final AtomicReference requestHeadersCapture = new AtomicReference<>(); private final AtomicReference contextCapture = @@ -1657,6 +1659,16 @@ public abstract class AbstractInteropTest { } } + /** + * Verifies remote server address and local client address are available from ClientCall + * Attributes via ClientInterceptor. + */ + @Test + public void getServerAddressAndLocalAddressFromClient() { + assertNotNull(obtainRemoteServerAddr()); + assertNotNull(obtainLocalClientAddr()); + } + /** Sends a large unary rpc with service account credentials. */ public void serviceAccountCreds(String jsonKey, InputStream credentialsStream, String authScope) throws Exception { @@ -1829,8 +1841,19 @@ public abstract class AbstractInteropTest { return serverCallCapture.get().getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR); } + /** Helper for getting remote address from {@link io.grpc.ClientCall#getAttributes()} */ + protected SocketAddress obtainRemoteServerAddr() { + TestServiceGrpc.TestServiceBlockingStub stub = blockingStub + .withInterceptors(recordClientCallInterceptor(clientCallCapture)) + .withDeadlineAfter(5, TimeUnit.SECONDS); + + stub.unaryCall(SimpleRequest.getDefaultInstance()); + + return clientCallCapture.get().getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR); + } + /** Helper for getting local address from {@link io.grpc.ServerCall#getAttributes()} */ - protected SocketAddress obtainLocalClientAddr() { + protected SocketAddress obtainLocalServerAddr() { TestServiceGrpc.TestServiceBlockingStub stub = blockingStub.withDeadlineAfter(5, TimeUnit.SECONDS); @@ -1839,6 +1862,17 @@ public abstract class AbstractInteropTest { return serverCallCapture.get().getAttributes().get(Grpc.TRANSPORT_ATTR_LOCAL_ADDR); } + /** Helper for getting local address from {@link io.grpc.ClientCall#getAttributes()} */ + protected SocketAddress obtainLocalClientAddr() { + TestServiceGrpc.TestServiceBlockingStub stub = blockingStub + .withInterceptors(recordClientCallInterceptor(clientCallCapture)) + .withDeadlineAfter(5, TimeUnit.SECONDS); + + stub.unaryCall(SimpleRequest.getDefaultInstance()); + + return clientCallCapture.get().getAttributes().get(Grpc.TRANSPORT_ATTR_LOCAL_ADDR); + } + /** Helper for asserting TLS info in SSLSession {@link io.grpc.ServerCall#getAttributes()} */ protected void assertX500SubjectDn(String tlsInfo) { TestServiceGrpc.TestServiceBlockingStub stub = @@ -2155,6 +2189,23 @@ public abstract class AbstractInteropTest { }; } + /** + * Captures the request attributes. Useful for testing ClientCalls. + * {@link ClientCall#getAttributes()} + */ + private static ClientInterceptor recordClientCallInterceptor( + final AtomicReference> clientCallCapture) { + return new ClientInterceptor() { + @Override + public ClientCall interceptCall( + MethodDescriptor method, CallOptions callOptions, Channel next) { + ClientCall clientCall = next.newCall(method,callOptions); + clientCallCapture.set(clientCall); + return clientCall; + } + }; + } + private static ServerInterceptor recordContextInterceptor( final AtomicReference contextCapture) { return new ServerInterceptor() { diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java index dd0f4ea17f..74c5147cc4 100644 --- a/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java +++ b/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java @@ -89,7 +89,7 @@ public class Http2NettyTest extends AbstractInteropTest { @Test public void localAddr() throws Exception { - InetSocketAddress isa = (InetSocketAddress) obtainLocalClientAddr(); + InetSocketAddress isa = (InetSocketAddress) obtainLocalServerAddr(); assertEquals(InetAddress.getLoopbackAddress(), isa.getAddress()); assertEquals(((InetSocketAddress) getListenAddress()).getPort(), isa.getPort()); }