netty: Move server transportReady after client preface receipt

This mirrors the behavior of client-side.
This commit is contained in:
Eric Anderson 2017-11-06 15:03:42 -08:00
parent ddae5ddaa5
commit 93e89ba704
2 changed files with 39 additions and 9 deletions

View File

@ -106,6 +106,9 @@ class NettyServerHandler extends AbstractNettyHandler {
private final List<ServerStreamTracer.Factory> streamTracerFactories;
private final TransportTracer transportTracer;
private final KeepAliveEnforcer keepAliveEnforcer;
/** Incomplete attributes produced by negotiator. */
private Attributes negotiationAttributes;
/** Completed attributes produced by transportReady. */
private Attributes attributes;
private Throwable connectionError;
private boolean teWarningLogged;
@ -481,7 +484,7 @@ class NettyServerHandler extends AbstractNettyHandler {
@Override
public void handleProtocolNegotiationCompleted(Attributes attrs) {
attributes = transportListener.transportReady(attrs);
negotiationAttributes = attrs;
}
@VisibleForTesting
@ -680,6 +683,17 @@ class NettyServerHandler extends AbstractNettyHandler {
}
private class FrameListener extends Http2FrameAdapter {
private boolean firstSettings = true;
@Override
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) {
if (firstSettings) {
firstSettings = false;
// Delay transportReady until we see the client's HTTP handshake, for coverage with
// handshakeTimeout
attributes = transportListener.transportReady(negotiationAttributes);
}
}
@Override
public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding,

View File

@ -89,13 +89,13 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
@ -136,7 +136,7 @@ public class NettyServerHandlerTest extends NettyHandlerTestBase<NettyServerHand
private long maxConnectionAgeGraceInNanos = MAX_CONNECTION_AGE_GRACE_NANOS_INFINITE;
private long keepAliveTimeInNanos = DEFAULT_SERVER_KEEPALIVE_TIME_NANOS;
private long keepAliveTimeoutInNanos = DEFAULT_SERVER_KEEPALIVE_TIMEOUT_NANOS;
private TransportTracer transportTracer;
private TransportTracer transportTracer = new TransportTracer();
private class ServerTransportListenerImpl implements ServerTransportListener {
@ -155,12 +155,10 @@ public class NettyServerHandlerTest extends NettyHandlerTestBase<NettyServerHand
}
}
@Override
protected void manualSetUp() throws Exception {
assertNull("manualSetUp should not run more than once", handler());
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
transportTracer = new TransportTracer();
when(streamTracerFactory.newServerStreamTracer(anyString(), any(Metadata.class)))
.thenReturn(streamTracer);
@ -178,7 +176,12 @@ public class NettyServerHandlerTest extends NettyHandlerTestBase<NettyServerHand
}
})
.when(streamListener)
.messagesAvailable(Matchers.<StreamListener.MessageProducer>any());
.messagesAvailable(any(StreamListener.MessageProducer.class));
}
@Override
protected void manualSetUp() throws Exception {
assertNull("manualSetUp should not run more than once", handler());
initChannel(new GrpcHttp2ServerHeadersDecoder(GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE));
@ -195,6 +198,19 @@ public class NettyServerHandlerTest extends NettyHandlerTestBase<NettyServerHand
channelRead(serializedSettings);
}
@Test
public void transportReadyDelayedUntilConnectionPreface() throws Exception {
initChannel(new GrpcHttp2ServerHeadersDecoder(GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE));
handler().handleProtocolNegotiationCompleted(Attributes.EMPTY);
verify(transportListener, never()).transportReady(any(Attributes.class));
// Simulate receipt of the connection preface
channelRead(Http2CodecUtil.connectionPrefaceBuf());
channelRead(serializeSettings(new Http2Settings()));
verify(transportListener).transportReady(any(Attributes.class));
}
@Test
public void sendFrameShouldSucceed() throws Exception {
manualSetUp();