Search in sources :

Example 51 with Http2Headers

use of io.netty.handler.codec.http2.Http2Headers in project grpc-java by grpc.

the class NettyClientHandler method createStream.

/**
 * Attempts to create a new stream from the given command. If there are too many active streams,
 * the creation request is queued.
 */
private void createStream(CreateStreamCommand command, ChannelPromise promise) throws Exception {
    if (lifecycleManager.getShutdownThrowable() != null) {
        command.stream().setNonExistent();
        // The connection is going away (it is really the GOAWAY case),
        // just terminate the stream now.
        command.stream().transportReportStatus(lifecycleManager.getShutdownStatus(), RpcProgress.MISCARRIED, true, new Metadata());
        promise.setFailure(lifecycleManager.getShutdownThrowable());
        return;
    }
    // Get the stream ID for the new stream.
    int streamId;
    try {
        streamId = incrementAndGetNextStreamId();
    } catch (StatusException e) {
        command.stream().setNonExistent();
        // Stream IDs have been exhausted for this connection. Fail the promise immediately.
        promise.setFailure(e);
        // Initiate a graceful shutdown if we haven't already.
        if (!connection().goAwaySent()) {
            logger.fine("Stream IDs have been exhausted for this connection. " + "Initiating graceful shutdown of the connection.");
            lifecycleManager.notifyShutdown(e.getStatus());
            close(ctx(), ctx().newPromise());
        }
        return;
    }
    if (connection().goAwayReceived()) {
        Status s = abruptGoAwayStatus;
        int maxActiveStreams = connection().local().maxActiveStreams();
        int lastStreamId = connection().local().lastStreamKnownByPeer();
        if (s == null) {
            // Should be impossible, but handle pseudo-gracefully
            s = Status.INTERNAL.withDescription("Failed due to abrupt GOAWAY, but can't find GOAWAY details");
        } else if (streamId > lastStreamId) {
            s = s.augmentDescription("stream id: " + streamId + ", GOAWAY Last-Stream-ID:" + lastStreamId);
        } else if (connection().local().numActiveStreams() == maxActiveStreams) {
            s = s.augmentDescription("At MAX_CONCURRENT_STREAMS limit. limit: " + maxActiveStreams);
        }
        if (streamId > lastStreamId || connection().local().numActiveStreams() == maxActiveStreams) {
            // This should only be reachable during onGoAwayReceived, as otherwise
            // getShutdownThrowable() != null
            command.stream().setNonExistent();
            command.stream().transportReportStatus(s, RpcProgress.MISCARRIED, true, new Metadata());
            promise.setFailure(s.asRuntimeException());
            return;
        }
    }
    NettyClientStream.TransportState stream = command.stream();
    Http2Headers headers = command.headers();
    stream.setId(streamId);
    PerfMark.startTask("NettyClientHandler.createStream", stream.tag());
    PerfMark.linkIn(command.getLink());
    try {
        createStreamTraced(streamId, stream, headers, command.isGet(), command.shouldBeCountedForInUse(), promise);
    } finally {
        PerfMark.stopTask("NettyClientHandler.createStream", stream.tag());
    }
}
Also used : Status(io.grpc.Status) StatusException(io.grpc.StatusException) Http2Headers(io.netty.handler.codec.http2.Http2Headers) Metadata(io.grpc.Metadata)

Example 52 with Http2Headers

use of io.netty.handler.codec.http2.Http2Headers in project grpc-java by grpc.

the class NettyClientStreamTest method inboundHeadersShouldCallListenerHeadersRead.

@Test
public void inboundHeadersShouldCallListenerHeadersRead() throws Exception {
    stream().transportState().setId(STREAM_ID);
    Http2Headers headers = grpcResponseHeaders();
    stream().transportState().transportHeadersReceived(headers, false);
    verify(listener).headersRead(any(Metadata.class));
}
Also used : Http2Headers(io.netty.handler.codec.http2.Http2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) Metadata(io.grpc.Metadata) Test(org.junit.Test)

Example 53 with Http2Headers

use of io.netty.handler.codec.http2.Http2Headers in project grpc-java by grpc.

the class NettyClientStreamTest method invalidInboundContentTypeShouldCancelStream.

@Test
public void invalidInboundContentTypeShouldCancelStream() {
    // Set stream id to indicate it has been created
    stream().transportState().setId(STREAM_ID);
    Http2Headers headers = new DefaultHttp2Headers().status(STATUS_OK).set(CONTENT_TYPE_HEADER, new AsciiString("application/bad", UTF_8));
    stream().transportState().transportHeadersReceived(headers, false);
    Http2Headers trailers = new DefaultHttp2Headers().set(new AsciiString("grpc-status", UTF_8), new AsciiString("0", UTF_8));
    stream().transportState().transportHeadersReceived(trailers, true);
    ArgumentCaptor<Status> captor = ArgumentCaptor.forClass(Status.class);
    ArgumentCaptor<Metadata> metadataCaptor = ArgumentCaptor.forClass(Metadata.class);
    verify(listener).closed(captor.capture(), same(PROCESSED), metadataCaptor.capture());
    Status status = captor.getValue();
    assertEquals(Status.Code.UNKNOWN, status.getCode());
    assertTrue(status.getDescription().contains("content-type"));
    assertEquals("application/bad", metadataCaptor.getValue().get(Metadata.Key.of("Content-Type", Metadata.ASCII_STRING_MARSHALLER)));
}
Also used : Status(io.grpc.Status) InternalStatus(io.grpc.InternalStatus) Http2Headers(io.netty.handler.codec.http2.Http2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) AsciiString(io.netty.util.AsciiString) Metadata(io.grpc.Metadata) Test(org.junit.Test)

Example 54 with Http2Headers

use of io.netty.handler.codec.http2.Http2Headers in project grpc-java by grpc.

the class NettyClientHandlerTest method bdpPingAvoidsTooManyPingsOnSpecialServers.

@Test
public void bdpPingAvoidsTooManyPingsOnSpecialServers() throws Exception {
    // gRPC servers limit PINGs based on what they _send_. Some servers limit PINGs based on what is
    // _received_.
    createStream();
    handler().setAutoTuneFlowControl(true);
    Http2Headers headers = new DefaultHttp2Headers().status(STATUS_OK).set(CONTENT_TYPE_HEADER, CONTENT_TYPE_GRPC);
    channelRead(headersFrame(3, headers));
    channelRead(dataFrame(3, false, content()));
    verifyWrite().writePing(eq(ctx()), eq(false), eq(1234L), any(ChannelPromise.class));
    channelRead(pingFrame(true, 1234));
    channelRead(dataFrame(3, false, content()));
    verifyWrite(times(2)).writePing(eq(ctx()), eq(false), eq(1234L), any(ChannelPromise.class));
    channelRead(pingFrame(true, 1234));
    channelRead(dataFrame(3, false, content()));
    // No ping was sent
    verifyWrite(times(2)).writePing(eq(ctx()), eq(false), eq(1234L), any(ChannelPromise.class));
}
Also used : Http2Headers(io.netty.handler.codec.http2.Http2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) ChannelPromise(io.netty.channel.ChannelPromise) Test(org.junit.Test)

Example 55 with Http2Headers

use of io.netty.handler.codec.http2.Http2Headers in project grpc-java by grpc.

the class NettyClientHandlerTest method inboundShouldForwardToStream.

@Test
public void inboundShouldForwardToStream() throws Exception {
    createStream();
    // Read a headers frame first.
    Http2Headers headers = new DefaultHttp2Headers().status(STATUS_OK).set(CONTENT_TYPE_HEADER, CONTENT_TYPE_GRPC).set(as("magic"), as("value"));
    ByteBuf headersFrame = headersFrame(3, headers);
    channelRead(headersFrame);
    ArgumentCaptor<Metadata> captor = ArgumentCaptor.forClass(Metadata.class);
    verify(streamListener).headersRead(captor.capture());
    assertEquals("value", captor.getValue().get(Metadata.Key.of("magic", Metadata.ASCII_STRING_MARSHALLER)));
    streamTransportState.requestMessagesFromDeframerForTesting(1);
    // Create a data frame and then trigger the handler to read it.
    ByteBuf frame = grpcDataFrame(3, false, contentAsArray());
    channelRead(frame);
    InputStream message = streamListenerMessageQueue.poll();
    assertArrayEquals(ByteBufUtil.getBytes(content()), ByteStreams.toByteArray(message));
    message.close();
    assertNull("no additional message expected", streamListenerMessageQueue.poll());
}
Also used : Http2Headers(io.netty.handler.codec.http2.Http2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) InputStream(java.io.InputStream) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) Metadata(io.grpc.Metadata) ByteBuf(io.netty.buffer.ByteBuf) Test(org.junit.Test)

Aggregations

Http2Headers (io.netty.handler.codec.http2.Http2Headers)126 DefaultHttp2Headers (io.netty.handler.codec.http2.DefaultHttp2Headers)111 ByteBuf (io.netty.buffer.ByteBuf)103 Test (org.junit.Test)97 ChannelFuture (io.netty.channel.ChannelFuture)76 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)76 AsciiString (io.netty.util.AsciiString)58 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)58 AtomicReference (java.util.concurrent.atomic.AtomicReference)56 ByteArrayOutputStream (java.io.ByteArrayOutputStream)54 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)54 Channel (io.netty.channel.Channel)53 Collections (java.util.Collections)53 ChannelInitializer (io.netty.channel.ChannelInitializer)52 ChannelPipeline (io.netty.channel.ChannelPipeline)52 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)52 HttpHeaderNames (io.netty.handler.codec.http.HttpHeaderNames)52 ApplicationProtocolNames (io.netty.handler.ssl.ApplicationProtocolNames)52 ApplicationProtocolNegotiationHandler (io.netty.handler.ssl.ApplicationProtocolNegotiationHandler)52 SslHandler (io.netty.handler.ssl.SslHandler)52