use of io.netty.channel.ChannelConfig in project netty by netty.
the class DefaultHttp2ConnectionEncoderTest method setup.
@BeforeEach
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
ChannelMetadata metadata = new ChannelMetadata(false, 16);
when(channel.isActive()).thenReturn(true);
when(channel.pipeline()).thenReturn(pipeline);
when(channel.metadata()).thenReturn(metadata);
when(channel.unsafe()).thenReturn(unsafe);
ChannelConfig config = new DefaultChannelConfig(channel);
when(channel.config()).thenReturn(config);
doAnswer(new Answer<ChannelFuture>() {
@Override
public ChannelFuture answer(InvocationOnMock in) {
return newPromise().setFailure((Throwable) in.getArgument(0));
}
}).when(channel).newFailedFuture(any(Throwable.class));
when(writer.configuration()).thenReturn(writerConfig);
when(writerConfig.frameSizePolicy()).thenReturn(frameSizePolicy);
when(frameSizePolicy.maxFrameSize()).thenReturn(64);
doAnswer(new Answer<ChannelFuture>() {
@Override
public ChannelFuture answer(InvocationOnMock in) throws Throwable {
return ((ChannelPromise) in.getArguments()[2]).setSuccess();
}
}).when(writer).writeSettings(eq(ctx), any(Http2Settings.class), any(ChannelPromise.class));
doAnswer(new Answer<ChannelFuture>() {
@Override
public ChannelFuture answer(InvocationOnMock in) throws Throwable {
((ByteBuf) in.getArguments()[3]).release();
return ((ChannelPromise) in.getArguments()[4]).setSuccess();
}
}).when(writer).writeGoAway(eq(ctx), anyInt(), anyInt(), any(ByteBuf.class), any(ChannelPromise.class));
writtenData = new ArrayList<String>();
writtenPadding = new ArrayList<Integer>();
when(writer.writeData(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean(), any(ChannelPromise.class))).then(new Answer<ChannelFuture>() {
@Override
public ChannelFuture answer(InvocationOnMock in) throws Throwable {
// Make sure we only receive stream closure on the last frame and that void promises
// are used for all writes except the last one.
ChannelPromise promise = (ChannelPromise) in.getArguments()[5];
if (streamClosed) {
fail("Stream already closed");
} else {
streamClosed = (Boolean) in.getArguments()[4];
}
writtenPadding.add((Integer) in.getArguments()[3]);
ByteBuf data = (ByteBuf) in.getArguments()[2];
writtenData.add(data.toString(UTF_8));
// Release the buffer just as DefaultHttp2FrameWriter does
data.release();
// Let the promise succeed to trigger listeners.
return promise.setSuccess();
}
});
when(writer.writeHeaders(eq(ctx), anyInt(), any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean(), any(ChannelPromise.class))).then(new Answer<ChannelFuture>() {
@Override
public ChannelFuture answer(InvocationOnMock invocationOnMock) {
ChannelPromise promise = invocationOnMock.getArgument(8);
if (streamClosed) {
fail("Stream already closed");
} else {
streamClosed = invocationOnMock.getArgument(5);
}
return promise.setSuccess();
}
});
when(writer.writeHeaders(eq(ctx), anyInt(), any(Http2Headers.class), anyInt(), anyBoolean(), any(ChannelPromise.class))).then(new Answer<ChannelFuture>() {
@Override
public ChannelFuture answer(InvocationOnMock invocationOnMock) {
ChannelPromise promise = invocationOnMock.getArgument(5);
if (streamClosed) {
fail("Stream already closed");
} else {
streamClosed = invocationOnMock.getArgument(4);
}
return promise.setSuccess();
}
});
payloadCaptor = ArgumentCaptor.forClass(Http2RemoteFlowController.FlowControlled.class);
doNothing().when(remoteFlow).addFlowControlled(any(Http2Stream.class), payloadCaptor.capture());
when(ctx.alloc()).thenReturn(UnpooledByteBufAllocator.DEFAULT);
when(ctx.channel()).thenReturn(channel);
doAnswer(new Answer<ChannelPromise>() {
@Override
public ChannelPromise answer(InvocationOnMock in) throws Throwable {
return newPromise();
}
}).when(ctx).newPromise();
doAnswer(new Answer<ChannelFuture>() {
@Override
public ChannelFuture answer(InvocationOnMock in) throws Throwable {
return newSucceededFuture();
}
}).when(ctx).newSucceededFuture();
when(ctx.flush()).thenThrow(new AssertionFailedError("forbidden"));
when(channel.alloc()).thenReturn(PooledByteBufAllocator.DEFAULT);
// Use a server-side connection so we can test server push.
connection = new DefaultHttp2Connection(true);
connection.remote().flowController(remoteFlow);
encoder = new DefaultHttp2ConnectionEncoder(connection, writer);
encoder.lifecycleManager(lifecycleManager);
}
use of io.netty.channel.ChannelConfig in project netty by netty.
the class AbstractOioMessageChannel method doRead.
@Override
protected void doRead() {
if (!readPending) {
// during the same read loop readPending was set to false.
return;
}
// In OIO we should set readPending to false even if the read was not successful so we can schedule
// another read on the event loop if no reads are done.
readPending = false;
final ChannelConfig config = config();
final ChannelPipeline pipeline = pipeline();
final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
allocHandle.reset(config);
boolean closed = false;
Throwable exception = null;
try {
do {
// Perform a read.
int localRead = doReadMessages(readBuf);
if (localRead == 0) {
break;
}
if (localRead < 0) {
closed = true;
break;
}
allocHandle.incMessagesRead(localRead);
} while (allocHandle.continueReading());
} catch (Throwable t) {
exception = t;
}
boolean readData = false;
int size = readBuf.size();
if (size > 0) {
readData = true;
for (int i = 0; i < size; i++) {
readPending = false;
pipeline.fireChannelRead(readBuf.get(i));
}
readBuf.clear();
allocHandle.readComplete();
pipeline.fireChannelReadComplete();
}
if (exception != null) {
if (exception instanceof IOException) {
closed = true;
}
pipeline.fireExceptionCaught(exception);
}
if (closed) {
if (isOpen()) {
unsafe().close(unsafe().voidPromise());
}
} else if (readPending || config.isAutoRead() || !readData && isActive()) {
// Reading 0 bytes could mean there is a SocketTimeout and no data was actually read, so we
// should execute read() again because no data may have been read.
read();
}
}
use of io.netty.channel.ChannelConfig in project grpc-java by grpc.
the class NettyClientTransportTest method setSoLingerChannelOption.
@Test
public void setSoLingerChannelOption() throws IOException {
startServer();
Map<ChannelOption<?>, Object> channelOptions = new HashMap<>();
// set SO_LINGER option
int soLinger = 123;
channelOptions.put(ChannelOption.SO_LINGER, soLinger);
NettyClientTransport transport = new NettyClientTransport(address, new ReflectiveChannelFactory<>(NioSocketChannel.class), channelOptions, group, newNegotiator(), false, DEFAULT_WINDOW_SIZE, DEFAULT_MAX_MESSAGE_SIZE, GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE, KEEPALIVE_TIME_NANOS_DISABLED, 1L, false, authority, null, /* user agent */
tooManyPingsRunnable, new TransportTracer(), Attributes.EMPTY, new SocketPicker(), new FakeChannelLogger(), false);
transports.add(transport);
callMeMaybe(transport.start(clientTransportListener));
// verify SO_LINGER has been set
ChannelConfig config = transport.channel().config();
assertTrue(config instanceof SocketChannelConfig);
assertEquals(soLinger, ((SocketChannelConfig) config).getSoLinger());
}
use of io.netty.channel.ChannelConfig in project pravega by pravega.
the class AppendProcessorTest method testOutstandingByteTracking.
/**
* Simulates multiple connections being set up and all sending appends (conditional or unconditional). Some may be
* failed by the store. Verifies that {@link ConnectionTracker#getTotalOutstanding()} does not drift with time,
* regardless of append outcome.
*/
@Test
public void testOutstandingByteTracking() throws Exception {
final int connectionCount = 5;
final int writersCount = 5;
final int segmentCount = 5;
val tracker = new ConnectionTracker();
val context = mock(ChannelHandlerContext.class);
val channel = mock(Channel.class);
val channelConfig = mock(ChannelConfig.class);
when(context.channel()).thenReturn(channel);
when(channel.config()).thenReturn(channelConfig);
val eventLoop = mock(EventLoop.class);
when(channel.eventLoop()).thenReturn(eventLoop);
when(eventLoop.inEventLoop()).thenReturn(false);
val channelFuture = mock(ChannelFuture.class);
when(channel.writeAndFlush(any())).thenReturn(channelFuture);
val segments = IntStream.range(0, segmentCount).mapToObj(Integer::toString).collect(Collectors.toList());
val writers = IntStream.range(0, writersCount).mapToObj(i -> UUID.randomUUID()).collect(Collectors.toList());
val store = mock(StreamSegmentStore.class);
val processors = new ArrayList<AppendProcessor>();
for (int i = 0; i < connectionCount; i++) {
val h = new ServerConnectionInboundHandler();
h.channelRegistered(context);
val p = AppendProcessor.defaultBuilder().store(store).connection(new TrackedConnection(h, tracker)).build();
processors.add(p);
}
// Setup appends.
for (int connectionId = 0; connectionId < processors.size(); connectionId++) {
for (val s : segments) {
for (val w : writers) {
when(store.getAttributes(s, Collections.singleton(AttributeId.fromUUID(w)), true, AppendProcessor.TIMEOUT)).thenReturn(CompletableFuture.completedFuture(Collections.singletonMap(AttributeId.fromUUID(w), 0L)));
processors.get(connectionId).setupAppend(new WireCommands.SetupAppend(0, w, s, null));
}
}
}
// Divide the segments into conditional and unconditional.
val conditionalSegments = segments.subList(0, segments.size() / 2);
val unconditionalSegments = segments.subList(conditionalSegments.size(), segments.size() - 1);
// Send a few appends to each connection from each writer.
val appendData = Unpooled.wrappedBuffer(new byte[1]);
when(store.append(any(), any(), any(), any())).thenReturn(delayedResponse(0L));
for (val s : unconditionalSegments) {
for (val p : processors) {
for (val w : writers) {
p.append(new Append(s, w, 1, new WireCommands.Event(appendData.retain()), 0));
}
}
}
// Send a few conditional appends to each connection from each writer. Fail some along the way.
int appendOffset = 0;
for (val s : conditionalSegments) {
for (val p : processors) {
for (val w : writers) {
boolean fail = appendOffset % 3 == 0;
if (fail) {
when(store.append(any(), any(long.class), any(), any(), any())).thenReturn(delayedFailure(new BadOffsetException(s, appendOffset, appendOffset)));
} else {
when(store.append(any(), any(long.class), any(), any(), any())).thenReturn(delayedResponse(0L));
}
p.append(new Append(s, w, 1, new WireCommands.Event(appendData.retain()), appendOffset, 0));
appendOffset++;
}
}
}
// Fail (attributes) all connections.
when(store.append(any(), any(), any(), any())).thenReturn(delayedFailure(new BadAttributeUpdateException("s", null, false, "intentional")));
for (val s : conditionalSegments) {
for (val p : processors) {
for (val w : writers) {
p.append(new Append(s, w, 1, new WireCommands.Event(appendData.retain()), 0));
}
}
}
// Verify that there is no drift in the ConnectionTracker#getTotalOutstanding value. Due to the async nature
// of the calls, this value may not immediately be updated.
AssertExtensions.assertEventuallyEquals(0L, tracker::getTotalOutstanding, 10000);
}
use of io.netty.channel.ChannelConfig in project netty by netty.
the class BootstrapTest method testChannelOptionOrderPreserve.
@Test
public void testChannelOptionOrderPreserve() throws InterruptedException {
final BlockingQueue<ChannelOption<?>> options = new LinkedBlockingQueue<ChannelOption<?>>();
class ChannelConfigValidator extends DefaultChannelConfig {
ChannelConfigValidator(Channel channel) {
super(channel);
}
@Override
public <T> boolean setOption(ChannelOption<T> option, T value) {
options.add(option);
return super.setOption(option, value);
}
}
final CountDownLatch latch = new CountDownLatch(1);
final Bootstrap bootstrap = new Bootstrap().handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
latch.countDown();
}
}).group(groupA).channelFactory(new ChannelFactory<Channel>() {
@Override
public Channel newChannel() {
return new LocalChannel() {
private ChannelConfigValidator config;
@Override
public synchronized ChannelConfig config() {
if (config == null) {
config = new ChannelConfigValidator(this);
}
return config;
}
};
}
}).option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 1).option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 2);
bootstrap.register().syncUninterruptibly();
latch.await();
// Check the order is the same as what we defined before.
assertSame(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, options.take());
assertSame(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, options.take());
}
Aggregations