Cleaning up the initialization of Http2ConnectionHandler

Motivation:

It currently takes a builder for the encoder and decoder, which makes it difficult to decorate them.

Modifications:

Removed the builders from the interfaces entirely. Left the builder for the decoder impl but removed it from the encoder since it's constructor only takes 2 parameters. Also added decorator base classes for the encoder and decoder and made the CompressorHttp2ConnectionEncoder extend the decorator.

Result:

Fixes #3530
This commit is contained in:
nmittler 2015-03-27 15:37:20 -07:00
parent cb63e34bda
commit 6fbca14f8a
15 changed files with 353 additions and 302 deletions

View File

@ -34,10 +34,10 @@ import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
/**
* A HTTP2 encoder that will compress data frames according to the {@code content-encoding} header for each stream.
* The compression provided by this class will be applied to the data for the entire stream.
* A decorating HTTP2 encoder that will compress data frames according to the {@code content-encoding} header for each
* stream. The compression provided by this class will be applied to the data for the entire stream.
*/
public class CompressorHttp2ConnectionEncoder extends DefaultHttp2ConnectionEncoder {
public class CompressorHttp2ConnectionEncoder extends DecoratingHttp2ConnectionEncoder {
private static final Http2ConnectionAdapter CLEAN_UP_LISTENER = new Http2ConnectionAdapter() {
@Override
public void streamRemoved(Http2Stream stream) {
@ -48,53 +48,33 @@ public class CompressorHttp2ConnectionEncoder extends DefaultHttp2ConnectionEnco
}
};
public static final int DEFAULT_COMPRESSION_LEVEL = 6;
public static final int DEFAULT_WINDOW_BITS = 15;
public static final int DEFAULT_MEM_LEVEL = 8;
private final int compressionLevel;
private final int windowBits;
private final int memLevel;
/**
* Builder for new instances of {@link CompressorHttp2ConnectionEncoder}
*/
public static class Builder extends DefaultHttp2ConnectionEncoder.Builder {
protected int compressionLevel = 6;
protected int windowBits = 15;
protected int memLevel = 8;
public CompressorHttp2ConnectionEncoder(Http2ConnectionEncoder delegate) {
this(delegate, DEFAULT_COMPRESSION_LEVEL, DEFAULT_WINDOW_BITS, DEFAULT_MEM_LEVEL);
}
public Builder compressionLevel(int compressionLevel) {
public CompressorHttp2ConnectionEncoder(Http2ConnectionEncoder delegate, int compressionLevel, int windowBits,
int memLevel) {
super(delegate);
if (compressionLevel < 0 || compressionLevel > 9) {
throw new IllegalArgumentException("compressionLevel: " + compressionLevel + " (expected: 0-9)");
}
if (windowBits < 9 || windowBits > 15) {
throw new IllegalArgumentException("windowBits: " + windowBits + " (expected: 9-15)");
}
if (memLevel < 1 || memLevel > 9) {
throw new IllegalArgumentException("memLevel: " + memLevel + " (expected: 1-9)");
}
this.compressionLevel = compressionLevel;
return this;
}
public Builder windowBits(int windowBits) {
this.windowBits = windowBits;
return this;
}
public Builder memLevel(int memLevel) {
this.memLevel = memLevel;
return this;
}
@Override
public CompressorHttp2ConnectionEncoder build() {
return new CompressorHttp2ConnectionEncoder(this);
}
}
protected CompressorHttp2ConnectionEncoder(Builder builder) {
super(builder);
if (builder.compressionLevel < 0 || builder.compressionLevel > 9) {
throw new IllegalArgumentException("compressionLevel: " + builder.compressionLevel + " (expected: 0-9)");
}
if (builder.windowBits < 9 || builder.windowBits > 15) {
throw new IllegalArgumentException("windowBits: " + builder.windowBits + " (expected: 9-15)");
}
if (builder.memLevel < 1 || builder.memLevel > 9) {
throw new IllegalArgumentException("memLevel: " + builder.memLevel + " (expected: 1-9)");
}
compressionLevel = builder.compressionLevel;
windowBits = builder.windowBits;
memLevel = builder.memLevel;
connection().addListener(CLEAN_UP_LISTENER);
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2015 The Netty Project
*
* The Netty Project licenses this file to you 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.netty.handler.codec.http2;
import static io.netty.util.internal.ObjectUtil.checkNotNull;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import java.util.List;
/**
* Decorator around another {@link Http2ConnectionDecoder} instance.
*/
public class DecoratingHttp2ConnectionDecoder implements Http2ConnectionDecoder {
private final Http2ConnectionDecoder delegate;
public DecoratingHttp2ConnectionDecoder(Http2ConnectionDecoder delegate) {
this.delegate = checkNotNull(delegate, "delegate");
}
@Override
public void lifecycleManager(Http2LifecycleManager lifecycleManager) {
delegate.lifecycleManager(lifecycleManager);
}
@Override
public Http2Connection connection() {
return delegate.connection();
}
@Override
public Http2LocalFlowController flowController() {
return delegate.flowController();
}
@Override
public Http2FrameListener listener() {
return delegate.listener();
}
@Override
public void decodeFrame(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Http2Exception {
delegate.decodeFrame(ctx, in, out);
}
@Override
public Http2Settings localSettings() {
return delegate.localSettings();
}
@Override
public void localSettings(Http2Settings settings) throws Http2Exception {
delegate.localSettings(settings);
}
@Override
public boolean prefaceReceived() {
return delegate.prefaceReceived();
}
@Override
public void close() {
delegate.close();
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2015 The Netty Project
*
* The Netty Project licenses this file to you 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.netty.handler.codec.http2;
import static io.netty.util.internal.ObjectUtil.checkNotNull;
/**
* A decorator around another {@link Http2ConnectionEncoder} instance.
*/
public class DecoratingHttp2ConnectionEncoder extends DecoratingHttp2FrameWriter implements Http2ConnectionEncoder {
private final Http2ConnectionEncoder delegate;
public DecoratingHttp2ConnectionEncoder(Http2ConnectionEncoder delegate) {
super(delegate);
this.delegate = checkNotNull(delegate, "delegate");
}
@Override
public void lifecycleManager(Http2LifecycleManager lifecycleManager) {
delegate.lifecycleManager(lifecycleManager);
}
@Override
public Http2Connection connection() {
return delegate.connection();
}
@Override
public Http2RemoteFlowController flowController() {
return delegate.flowController();
}
@Override
public Http2FrameWriter frameWriter() {
return delegate.frameWriter();
}
@Override
public Http2Settings pollSentSettings() {
return delegate.pollSentSettings();
}
@Override
public void remoteSettings(Http2Settings settings) throws Http2Exception {
delegate.remoteSettings(settings);
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright 2015 The Netty Project
*
* The Netty Project licenses this file to you 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.netty.handler.codec.http2;
import static io.netty.util.internal.ObjectUtil.checkNotNull;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
/**
* Decorator around another {@link Http2FrameWriter} instance.
*/
public class DecoratingHttp2FrameWriter implements Http2FrameWriter {
private final Http2FrameWriter delegate;
public DecoratingHttp2FrameWriter(Http2FrameWriter delegate) {
this.delegate = checkNotNull(delegate, "delegate");
}
@Override
public ChannelFuture writeData(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding,
boolean endStream, ChannelPromise promise) {
return delegate.writeData(ctx, streamId, data, padding, endStream, promise);
}
@Override
public ChannelFuture writeHeaders(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding,
boolean endStream, ChannelPromise promise) {
return delegate.writeHeaders(ctx, streamId, headers, padding, endStream, promise);
}
@Override
public ChannelFuture writeHeaders(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
int streamDependency, short weight, boolean exclusive, int padding,
boolean endStream, ChannelPromise promise) {
return delegate
.writeHeaders(ctx, streamId, headers, streamDependency, weight, exclusive, padding, endStream, promise);
}
@Override
public ChannelFuture writePriority(ChannelHandlerContext ctx, int streamId, int streamDependency, short weight,
boolean exclusive, ChannelPromise promise) {
return delegate.writePriority(ctx, streamId, streamDependency, weight, exclusive, promise);
}
@Override
public ChannelFuture writeRstStream(ChannelHandlerContext ctx, int streamId, long errorCode,
ChannelPromise promise) {
return delegate.writeRstStream(ctx, streamId, errorCode, promise);
}
@Override
public ChannelFuture writeSettings(ChannelHandlerContext ctx, Http2Settings settings, ChannelPromise promise) {
return delegate.writeSettings(ctx, settings, promise);
}
@Override
public ChannelFuture writeSettingsAck(ChannelHandlerContext ctx, ChannelPromise promise) {
return delegate.writeSettingsAck(ctx, promise);
}
@Override
public ChannelFuture writePing(ChannelHandlerContext ctx, boolean ack, ByteBuf data, ChannelPromise promise) {
return delegate.writePing(ctx, ack, data, promise);
}
@Override
public ChannelFuture writePushPromise(ChannelHandlerContext ctx, int streamId, int promisedStreamId,
Http2Headers headers, int padding, ChannelPromise promise) {
return delegate.writePushPromise(ctx, streamId, promisedStreamId, headers, padding, promise);
}
@Override
public ChannelFuture writeGoAway(ChannelHandlerContext ctx, int lastStreamId, long errorCode, ByteBuf debugData,
ChannelPromise promise) {
return delegate.writeGoAway(ctx, lastStreamId, errorCode, debugData, promise);
}
@Override
public ChannelFuture writeWindowUpdate(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement,
ChannelPromise promise) {
return delegate.writeWindowUpdate(ctx, streamId, windowSizeIncrement, promise);
}
@Override
public ChannelFuture writeFrame(ChannelHandlerContext ctx, byte frameType, int streamId, Http2Flags flags,
ByteBuf payload, ChannelPromise promise) {
return delegate.writeFrame(ctx, frameType, streamId, flags, payload, promise);
}
@Override
public Configuration configuration() {
return delegate.configuration();
}
@Override
public void close() {
delegate.close();
}
}

View File

@ -40,87 +40,40 @@ import java.util.List;
public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
private Http2FrameListener internalFrameListener = new PrefaceFrameListener();
private final Http2Connection connection;
private final Http2LifecycleManager lifecycleManager;
private Http2LifecycleManager lifecycleManager;
private final Http2ConnectionEncoder encoder;
private final Http2FrameReader frameReader;
private final Http2FrameListener listener;
private final Http2PromisedRequestVerifier requestVerifier;
/**
* Builder for instances of {@link DefaultHttp2ConnectionDecoder}.
*/
public static class Builder implements Http2ConnectionDecoder.Builder {
private Http2Connection connection;
private Http2LifecycleManager lifecycleManager;
private Http2ConnectionEncoder encoder;
private Http2FrameReader frameReader;
private Http2FrameListener listener;
private Http2PromisedRequestVerifier requestVerifier = ALWAYS_VERIFY;
@Override
public Builder connection(Http2Connection connection) {
this.connection = connection;
return this;
public DefaultHttp2ConnectionDecoder(Http2Connection connection,
Http2ConnectionEncoder encoder,
Http2FrameReader frameReader,
Http2FrameListener listener) {
this(connection, encoder, frameReader, listener, ALWAYS_VERIFY);
}
@Override
public Builder lifecycleManager(Http2LifecycleManager lifecycleManager) {
this.lifecycleManager = lifecycleManager;
return this;
}
@Override
public Http2LifecycleManager lifecycleManager() {
return lifecycleManager;
}
@Override
public Builder frameReader(Http2FrameReader frameReader) {
this.frameReader = frameReader;
return this;
}
@Override
public Builder listener(Http2FrameListener listener) {
this.listener = listener;
return this;
}
@Override
public Builder encoder(Http2ConnectionEncoder encoder) {
this.encoder = encoder;
return this;
}
@Override
public Http2ConnectionDecoder.Builder requestVerifier(Http2PromisedRequestVerifier requestVerifier) {
this.requestVerifier = requestVerifier;
return this;
}
@Override
public Http2ConnectionDecoder build() {
return new DefaultHttp2ConnectionDecoder(this);
}
}
public static Builder newBuilder() {
return new Builder();
}
protected DefaultHttp2ConnectionDecoder(Builder builder) {
connection = checkNotNull(builder.connection, "connection");
frameReader = checkNotNull(builder.frameReader, "frameReader");
lifecycleManager = checkNotNull(builder.lifecycleManager, "lifecycleManager");
encoder = checkNotNull(builder.encoder, "encoder");
listener = checkNotNull(builder.listener, "listener");
requestVerifier = checkNotNull(builder.requestVerifier, "requestVerifier");
public DefaultHttp2ConnectionDecoder(Http2Connection connection,
Http2ConnectionEncoder encoder,
Http2FrameReader frameReader,
Http2FrameListener listener,
Http2PromisedRequestVerifier requestVerifier) {
this.connection = checkNotNull(connection, "connection");
this.frameReader = checkNotNull(frameReader, "frameReader");
this.encoder = checkNotNull(encoder, "encoder");
this.listener = checkNotNull(listener, "listener");
this.requestVerifier = checkNotNull(requestVerifier, "requestVerifier");
if (connection.local().flowController() == null) {
connection.local().flowController(
new DefaultHttp2LocalFlowController(connection, encoder.frameWriter()));
}
}
@Override
public void lifecycleManager(Http2LifecycleManager lifecycleManager) {
this.lifecycleManager = checkNotNull(lifecycleManager, "lifecycleManager");
}
@Override
public Http2Connection connection() {
return connection;

View File

@ -35,63 +35,24 @@ import java.util.ArrayDeque;
public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
private final Http2FrameWriter frameWriter;
private final Http2Connection connection;
private final Http2LifecycleManager lifecycleManager;
private Http2LifecycleManager lifecycleManager;
// We prefer ArrayDeque to LinkedList because later will produce more GC.
// This initial capacity is plenty for SETTINGS traffic.
private final ArrayDeque<Http2Settings> outstandingLocalSettingsQueue = new ArrayDeque<Http2Settings>(4);
/**
* Builder for new instances of {@link DefaultHttp2ConnectionEncoder}.
*/
public static class Builder implements Http2ConnectionEncoder.Builder {
protected Http2FrameWriter frameWriter;
protected Http2Connection connection;
protected Http2LifecycleManager lifecycleManager;
@Override
public Builder connection(
Http2Connection connection) {
this.connection = connection;
return this;
}
@Override
public Builder lifecycleManager(
Http2LifecycleManager lifecycleManager) {
this.lifecycleManager = lifecycleManager;
return this;
}
@Override
public Http2LifecycleManager lifecycleManager() {
return lifecycleManager;
}
@Override
public Builder frameWriter(Http2FrameWriter frameWriter) {
this.frameWriter = frameWriter;
return this;
}
@Override
public Http2ConnectionEncoder build() {
return new DefaultHttp2ConnectionEncoder(this);
}
}
public static Builder newBuilder() {
return new Builder();
}
protected DefaultHttp2ConnectionEncoder(Builder builder) {
connection = checkNotNull(builder.connection, "connection");
frameWriter = checkNotNull(builder.frameWriter, "frameWriter");
lifecycleManager = checkNotNull(builder.lifecycleManager, "lifecycleManager");
public DefaultHttp2ConnectionEncoder(Http2Connection connection, Http2FrameWriter frameWriter) {
this.connection = checkNotNull(connection, "connection");
this.frameWriter = checkNotNull(frameWriter, "frameWriter");
if (connection.remote().flowController() == null) {
connection.remote().flowController(new DefaultHttp2RemoteFlowController(connection));
}
}
@Override
public void lifecycleManager(Http2LifecycleManager lifecycleManager) {
this.lifecycleManager = checkNotNull(lifecycleManager, "lifecycleManager");
}
@Override
public Http2FrameWriter frameWriter() {
return frameWriter;

View File

@ -29,49 +29,9 @@ import java.util.List;
public interface Http2ConnectionDecoder extends Closeable {
/**
* Builder for new instances of {@link Http2ConnectionDecoder}.
* Sets the lifecycle manager. Must be called as part of initialization before the decoder is used.
*/
interface Builder {
/**
* Sets the {@link Http2Connection} to be used when building the decoder.
*/
Builder connection(Http2Connection connection);
/**
* Sets the {@link Http2LifecycleManager} to be used when building the decoder.
*/
Builder lifecycleManager(Http2LifecycleManager lifecycleManager);
/**
* Gets the {@link Http2LifecycleManager} to be used when building the decoder.
*/
Http2LifecycleManager lifecycleManager();
/**
* Sets the {@link Http2FrameReader} to be used when building the decoder.
*/
Builder frameReader(Http2FrameReader frameReader);
/**
* Sets the {@link Http2FrameListener} to be used when building the decoder.
*/
Builder listener(Http2FrameListener listener);
/**
* Sets the {@link Http2ConnectionEncoder} used when building the decoder.
*/
Builder encoder(Http2ConnectionEncoder encoder);
/**
* Sets the {@link Http2PromisedRequestVerifier} used when building the decoder.
*/
Builder requestVerifier(Http2PromisedRequestVerifier requestVerifier);
/**
* Creates a new decoder instance.
*/
Http2ConnectionDecoder build();
}
void lifecycleManager(Http2LifecycleManager lifecycleManager);
/**
* Provides direct access to the underlying connection.

View File

@ -26,35 +26,9 @@ import io.netty.channel.ChannelPromise;
public interface Http2ConnectionEncoder extends Http2FrameWriter {
/**
* Builder for new instances of {@link Http2ConnectionEncoder}.
* Sets the lifecycle manager. Must be called as part of initialization before the encoder is used.
*/
interface Builder {
/**
* Sets the {@link Http2Connection} to be used when building the encoder.
*/
Builder connection(Http2Connection connection);
/**
* Sets the {@link Http2LifecycleManager} to be used when building the encoder.
*/
Builder lifecycleManager(Http2LifecycleManager lifecycleManager);
/**
* Gets the {@link Http2LifecycleManager} to be used when building the encoder.
*/
Http2LifecycleManager lifecycleManager();
/**
* Sets the {@link Http2FrameWriter} to be used when building the encoder.
*/
Builder frameWriter(Http2FrameWriter frameWriter);
/**
* Creates a new encoder instance.
*/
Http2ConnectionEncoder build();
}
void lifecycleManager(Http2LifecycleManager lifecycleManager);
/**
* Provides direct access to the underlying connection.

View File

@ -64,37 +64,18 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
public Http2ConnectionHandler(Http2Connection connection, Http2FrameReader frameReader,
Http2FrameWriter frameWriter, Http2FrameListener listener) {
this(DefaultHttp2ConnectionDecoder.newBuilder().connection(connection)
.frameReader(frameReader).listener(listener),
DefaultHttp2ConnectionEncoder.newBuilder().connection(connection)
.frameWriter(frameWriter));
encoder = new DefaultHttp2ConnectionEncoder(connection, frameWriter);
decoder = new DefaultHttp2ConnectionDecoder(connection, encoder, frameReader, listener);
}
/**
* Constructor for pre-configured encoder and decoder builders. Just sets the {@code this} as the
* Constructor for pre-configured encoder and decoder. Just sets the {@code this} as the
* {@link Http2LifecycleManager} and builds them.
*/
public Http2ConnectionHandler(Http2ConnectionDecoder.Builder decoderBuilder,
Http2ConnectionEncoder.Builder encoderBuilder) {
checkNotNull(decoderBuilder, "decoderBuilder");
checkNotNull(encoderBuilder, "encoderBuilder");
if (encoderBuilder.lifecycleManager() != decoderBuilder.lifecycleManager()) {
throw new IllegalArgumentException("Encoder and Decoder must share a lifecycle manager");
} else if (encoderBuilder.lifecycleManager() == null) {
encoderBuilder.lifecycleManager(this);
decoderBuilder.lifecycleManager(this);
}
// Build the encoder.
encoder = checkNotNull(encoderBuilder.build(), "encoder");
// Build the decoder.
decoderBuilder.encoder(encoder);
decoder = checkNotNull(decoderBuilder.build(), "decoder");
// Verify that the encoder and decoder use the same connection.
checkNotNull(encoder.connection(), "encoder.connection");
public Http2ConnectionHandler(Http2ConnectionDecoder decoder,
Http2ConnectionEncoder encoder) {
this.decoder = checkNotNull(decoder, "decoder");
this.encoder = checkNotNull(encoder, "encoder");
if (encoder.connection() != decoder.connection()) {
throw new IllegalArgumentException("Encoder and Decoder do not share the same connection object");
}
@ -304,6 +285,9 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
// Initialize the encoder and decoder.
encoder.lifecycleManager(this);
decoder.lifecycleManager(this);
byteDecoder = new PrefaceDecoder(ctx);
}

View File

@ -40,9 +40,9 @@ public class HttpToHttp2ConnectionHandler extends Http2ConnectionHandler {
super(connection, frameReader, frameWriter, listener);
}
public HttpToHttp2ConnectionHandler(Http2ConnectionDecoder.Builder decoderBuilder,
Http2ConnectionEncoder.Builder encoderBuilder) {
super(decoderBuilder, encoderBuilder);
public HttpToHttp2ConnectionHandler(Http2ConnectionDecoder decoder,
Http2ConnectionEncoder encoder) {
super(decoder, encoder);
}
/**

View File

@ -216,7 +216,7 @@ public class DataCompressionHttp2Test {
});
awaitServer();
assertEquals(0, serverConnection.local().flowController().unconsumedBytes(stream));
assertEquals(new StringBuilder(text1).append(text2).toString(),
assertEquals(text1 + text2,
serverOut.toString(CharsetUtil.UTF_8.name()));
} finally {
data1.release();
@ -296,16 +296,13 @@ public class DataCompressionHttp2Test {
@Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
Http2FrameWriter writer = new DefaultHttp2FrameWriter();
Http2ConnectionHandler connectionHandler =
new Http2ConnectionHandler(new DefaultHttp2ConnectionDecoder.Builder()
.connection(serverConnection)
.frameReader(new DefaultHttp2FrameReader())
.listener(
Http2ConnectionEncoder encoder = new CompressorHttp2ConnectionEncoder(
new DefaultHttp2ConnectionEncoder(serverConnection, new DefaultHttp2FrameWriter()));
Http2ConnectionDecoder decoder =
new DefaultHttp2ConnectionDecoder(serverConnection, encoder, new DefaultHttp2FrameReader(),
new DelegatingDecompressorFrameListener(serverConnection,
serverListener)),
new CompressorHttp2ConnectionEncoder.Builder().connection(
serverConnection).frameWriter(writer));
serverListener));
Http2ConnectionHandler connectionHandler = new Http2ConnectionHandler(decoder, encoder);
p.addLast(connectionHandler);
serverChannelLatch.countDown();
}
@ -319,17 +316,14 @@ public class DataCompressionHttp2Test {
ChannelPipeline p = ch.pipeline();
FrameCountDown clientFrameCountDown = new FrameCountDown(clientListener,
clientSettingsAckLatch, clientLatch);
Http2FrameWriter writer = new DefaultHttp2FrameWriter();
Http2ConnectionHandler connectionHandler =
new Http2ConnectionHandler(new DefaultHttp2ConnectionDecoder.Builder()
.connection(clientConnection)
.frameReader(new DefaultHttp2FrameReader())
.listener(
clientEncoder = new CompressorHttp2ConnectionEncoder(
new DefaultHttp2ConnectionEncoder(clientConnection, new DefaultHttp2FrameWriter()));
Http2ConnectionDecoder decoder =
new DefaultHttp2ConnectionDecoder(clientConnection, clientEncoder,
new DefaultHttp2FrameReader(),
new DelegatingDecompressorFrameListener(clientConnection,
clientFrameCountDown)),
new CompressorHttp2ConnectionEncoder.Builder().connection(
clientConnection).frameWriter(writer));
clientEncoder = connectionHandler.encoder();
clientFrameCountDown));
Http2ConnectionHandler connectionHandler = new Http2ConnectionHandler(decoder, clientEncoder);
p.addLast(connectionHandler);
}
});

View File

@ -139,9 +139,8 @@ public class DefaultHttp2ConnectionDecoderTest {
when(ctx.newPromise()).thenReturn(promise);
when(ctx.write(any())).thenReturn(future);
decoder = DefaultHttp2ConnectionDecoder.newBuilder().connection(connection)
.frameReader(reader).encoder(encoder)
.listener(listener).lifecycleManager(lifecycleManager).build();
decoder = new DefaultHttp2ConnectionDecoder(connection, encoder, reader, listener);
decoder.lifecycleManager(lifecycleManager);
// Simulate receiving the initial settings from the remote endpoint.
decode().onSettingsRead(ctx, new Http2Settings());

View File

@ -195,8 +195,8 @@ public class DefaultHttp2ConnectionEncoderTest {
when(ctx.newPromise()).thenReturn(promise);
when(ctx.write(any())).thenReturn(future);
encoder = DefaultHttp2ConnectionEncoder.newBuilder().connection(connection)
.frameWriter(writer).lifecycleManager(lifecycleManager).build();
encoder = new DefaultHttp2ConnectionEncoder(connection, writer);
encoder.lifecycleManager(lifecycleManager);
}
@Test

View File

@ -89,12 +89,6 @@ public class Http2ConnectionHandlerTest {
@Mock
private Http2Stream stream;
@Mock
private Http2ConnectionDecoder.Builder decoderBuilder;
@Mock
private Http2ConnectionEncoder.Builder encoderBuilder;
@Mock
private Http2ConnectionDecoder decoder;
@ -110,8 +104,6 @@ public class Http2ConnectionHandlerTest {
promise = new DefaultChannelPromise(channel);
when(encoderBuilder.build()).thenReturn(encoder);
when(decoderBuilder.build()).thenReturn(decoder);
when(encoder.connection()).thenReturn(connection);
when(decoder.connection()).thenReturn(connection);
when(encoder.frameWriter()).thenReturn(frameWriter);
@ -132,7 +124,7 @@ public class Http2ConnectionHandlerTest {
}
private Http2ConnectionHandler newHandler() throws Exception {
Http2ConnectionHandler handler = new Http2ConnectionHandler(decoderBuilder, encoderBuilder);
Http2ConnectionHandler handler = new Http2ConnectionHandler(decoder, encoder);
handler.handlerAdded(ctx);
return handler;
}

View File

@ -52,6 +52,8 @@ import io.netty.handler.codec.http2.DefaultHttp2FrameReader;
import io.netty.handler.codec.http2.DefaultHttp2FrameWriter;
import io.netty.handler.codec.http2.DefaultHttp2Headers;
import io.netty.handler.codec.http2.Http2Connection;
import io.netty.handler.codec.http2.Http2ConnectionDecoder;
import io.netty.handler.codec.http2.Http2ConnectionEncoder;
import io.netty.handler.codec.http2.Http2ConnectionHandler;
import io.netty.handler.codec.http2.Http2FrameAdapter;
import io.netty.handler.codec.http2.Http2FrameWriter;
@ -264,11 +266,11 @@ public class Http2FrameWriterBenchmark extends AbstractSharedExecutorMicrobenchm
connection.local().flowController(localFlowController);
}
environment.writer(new DefaultHttp2FrameWriter());
Http2ConnectionHandler connectionHandler = new Http2ConnectionHandler(
new DefaultHttp2ConnectionDecoder.Builder().connection(connection)
.frameReader(new DefaultHttp2FrameReader()).listener(new Http2FrameAdapter()),
new DefaultHttp2ConnectionEncoder.Builder().connection(connection).frameWriter(
environment.writer()));
Http2ConnectionEncoder encoder = new DefaultHttp2ConnectionEncoder(connection, environment.writer());
Http2ConnectionDecoder decoder =
new DefaultHttp2ConnectionDecoder(connection, encoder, new DefaultHttp2FrameReader(),
new Http2FrameAdapter());
Http2ConnectionHandler connectionHandler = new Http2ConnectionHandler(decoder, encoder);
p.addLast(connectionHandler);
environment.context(p.lastContext());
}
@ -283,10 +285,11 @@ public class Http2FrameWriterBenchmark extends AbstractSharedExecutorMicrobenchm
private static Environment boostrapEmbeddedEnv(final ByteBufAllocator alloc) {
final EmbeddedEnvironment env = new EmbeddedEnvironment(new DefaultHttp2FrameWriter());
final Http2Connection connection = new DefaultHttp2Connection(false);
final Http2ConnectionHandler connectionHandler = new Http2ConnectionHandler(
new DefaultHttp2ConnectionDecoder.Builder().connection(connection)
.frameReader(new DefaultHttp2FrameReader()).listener(new Http2FrameAdapter()),
new DefaultHttp2ConnectionEncoder.Builder().connection(connection).frameWriter(env.writer()));
Http2ConnectionEncoder encoder = new DefaultHttp2ConnectionEncoder(connection, env.writer());
Http2ConnectionDecoder decoder =
new DefaultHttp2ConnectionDecoder(connection, encoder, new DefaultHttp2FrameReader(),
new Http2FrameAdapter());
Http2ConnectionHandler connectionHandler = new Http2ConnectionHandler(decoder, encoder);
env.context(new EmbeddedChannelWriteReleaseHandlerContext(alloc, connectionHandler) {
@Override
protected void handleException(Throwable t) {