use of io.netty.channel.ChannelOutboundHandlerAdapter in project flink by apache.
the class ClientTransportErrorHandlingTest method testExceptionOnWrite.
/**
* Verifies that failed client requests via {@link PartitionRequestClient} are correctly
* attributed to the respective {@link RemoteInputChannel}.
*/
@Test
public void testExceptionOnWrite() throws Exception {
NettyProtocol protocol = new NettyProtocol() {
@Override
public ChannelHandler[] getServerChannelHandlers() {
return new ChannelHandler[0];
}
@Override
public ChannelHandler[] getClientChannelHandlers() {
return new PartitionRequestProtocol(mock(ResultPartitionProvider.class), mock(TaskEventDispatcher.class), mock(NetworkBufferPool.class)).getClientChannelHandlers();
}
};
// We need a real server and client in this test, because Netty's EmbeddedChannel is
// not failing the ChannelPromise of failed writes.
NettyServerAndClient serverAndClient = initServerAndClient(protocol, createConfig());
Channel ch = connect(serverAndClient);
PartitionRequestClientHandler handler = getClientHandler(ch);
// Last outbound handler throws Exception after 1st write
ch.pipeline().addFirst(new ChannelOutboundHandlerAdapter() {
int writeNum = 0;
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (writeNum >= 1) {
throw new RuntimeException("Expected test exception.");
}
writeNum++;
ctx.write(msg, promise);
}
});
PartitionRequestClient requestClient = new PartitionRequestClient(ch, handler, mock(ConnectionID.class), mock(PartitionRequestClientFactory.class));
// Create input channels
RemoteInputChannel[] rich = new RemoteInputChannel[] { createRemoteInputChannel(), createRemoteInputChannel() };
final CountDownLatch sync = new CountDownLatch(1);
// Do this with explicit synchronization. Otherwise this is not robust against slow timings
// of the callback (e.g. we cannot just verify that it was called once, because there is
// a chance that we do this too early).
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
sync.countDown();
return null;
}
}).when(rich[1]).onError(isA(LocalTransportException.class));
// First request is successful
ChannelFuture f = requestClient.requestSubpartition(new ResultPartitionID(), 0, rich[0], 0);
assertTrue(f.await().isSuccess());
// Second request is *not* successful
f = requestClient.requestSubpartition(new ResultPartitionID(), 0, rich[1], 0);
assertFalse(f.await().isSuccess());
// Only the second channel should be notified about the error
verify(rich[0], times(0)).onError(any(LocalTransportException.class));
// Wait for the notification
if (!sync.await(TestingUtils.TESTING_DURATION().toMillis(), TimeUnit.MILLISECONDS)) {
fail("Timed out after waiting for " + TestingUtils.TESTING_DURATION().toMillis() + " ms to be notified about the channel error.");
}
shutdown(serverAndClient);
}
use of io.netty.channel.ChannelOutboundHandlerAdapter in project MinecraftForge by MinecraftForge.
the class PacketLoggingHandler method register.
public static void register(NetworkManager manager) {
ChannelPipeline pipeline = manager.channel().pipeline();
final EnumPacketDirection direction = manager.getDirection();
if (manager.isLocalChannel()) {
pipeline.addBefore("packet_handler", "splitter", new SimpleChannelInboundHandler<Packet<?>>() {
String prefix = (direction == EnumPacketDirection.SERVERBOUND ? "SERVER: C->S" : "CLIENT: S->C");
@Override
protected void channelRead0(ChannelHandlerContext ctx, Packet<?> msg) throws Exception {
PacketBuffer buf = new PacketBuffer(Unpooled.buffer());
msg.writePacketData(buf);
FMLLog.log(Level.DEBUG, "%s %s:\n%s", prefix, msg.getClass().getSimpleName(), ByteBufUtils.getContentDump(buf));
ctx.fireChannelRead(msg);
}
});
pipeline.addBefore("splitter", "prepender", new ChannelOutboundHandlerAdapter() {
String prefix = (direction == EnumPacketDirection.SERVERBOUND ? "SERVER: S->C" : "CLIENT: C->S");
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (msg instanceof Packet<?>) {
PacketBuffer buf = new PacketBuffer(Unpooled.buffer());
((Packet<?>) msg).writePacketData(buf);
FMLLog.log(Level.DEBUG, "%s %s:\n%s", prefix, msg.getClass().getSimpleName(), ByteBufUtils.getContentDump(buf));
}
ctx.write(msg, promise);
}
});
} else {
pipeline.replace("splitter", "splitter", new NettyVarint21FrameDecoder() {
String prefix = (direction == EnumPacketDirection.SERVERBOUND ? "SERVER: C->S" : "CLIENT: S->C");
@Override
protected void decode(ChannelHandlerContext context, ByteBuf input, List<Object> output) throws Exception {
super.decode(context, input, output);
Iterator<Object> itr = output.iterator();
while (itr.hasNext()) {
ByteBuf pkt = (ByteBuf) itr.next();
pkt.markReaderIndex();
FMLLog.log(Level.DEBUG, "%s:\n%s", prefix, ByteBufUtils.getContentDump(pkt));
pkt.resetReaderIndex();
}
}
});
pipeline.replace("prepender", "prepender", new NettyVarint21FrameEncoder() {
String prefix = (direction == EnumPacketDirection.SERVERBOUND ? "SERVER: S->C" : "CLIENT: C->S");
@Override
protected void encode(ChannelHandlerContext context, ByteBuf input, ByteBuf output) throws Exception {
input.markReaderIndex();
FMLLog.log(Level.DEBUG, "%s:\n%s", prefix, ByteBufUtils.getContentDump(input));
input.resetReaderIndex();
super.encode(context, input, output);
}
});
}
}
use of io.netty.channel.ChannelOutboundHandlerAdapter in project netty by netty.
the class EmbeddedChannelTest method testWriteLater.
@Test
public void testWriteLater() {
EmbeddedChannel channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter() {
@Override
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) throws Exception {
ctx.executor().execute(new Runnable() {
@Override
public void run() {
ctx.write(msg, promise);
}
});
}
});
Object msg = new Object();
assertTrue(channel.writeOutbound(msg));
assertTrue(channel.finish());
assertSame(msg, channel.readOutbound());
assertNull(channel.readOutbound());
}
use of io.netty.channel.ChannelOutboundHandlerAdapter in project netty by netty.
the class EmbeddedChannelTest method testWriteOneOutbound.
@Test
public void testWriteOneOutbound() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicInteger flushCount = new AtomicInteger(0);
EmbeddedChannel channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter() {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
ctx.write(msg, promise);
latch.countDown();
}
@Override
public void flush(ChannelHandlerContext ctx) throws Exception {
flushCount.incrementAndGet();
}
});
// This shouldn't trigger a #flush()
channel.writeOneOutbound("Hello, Netty!");
if (!latch.await(1L, TimeUnit.SECONDS)) {
fail("Nobody called #write() in time.");
}
channel.close().syncUninterruptibly();
// There was no #flushOutbound() call so nobody should have called #flush()
assertEquals(0, flushCount.get());
}
use of io.netty.channel.ChannelOutboundHandlerAdapter in project netty by netty.
the class EmbeddedChannelTest method testFlushOutbound.
@Test
public void testFlushOutbound() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
EmbeddedChannel channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter() {
@Override
public void flush(ChannelHandlerContext ctx) throws Exception {
latch.countDown();
}
});
channel.flushOutbound();
if (!latch.await(1L, TimeUnit.SECONDS)) {
fail("Nobody called #flush() in time.");
}
}
Aggregations