use of io.netty.util.concurrent.PromiseNotifier in project netty by netty.
the class SslHandlerTest method testCloseNotify.
private static void testCloseNotify(SslProvider provider, final long closeNotifyReadTimeout, final boolean timeout) throws Exception {
SelfSignedCertificate ssc = new SelfSignedCertificate();
final SslContext sslServerCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).sslProvider(provider).build();
final SslContext sslClientCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).sslProvider(provider).build();
EventLoopGroup group = new NioEventLoopGroup();
Channel sc = null;
Channel cc = null;
try {
final Promise<Channel> clientPromise = group.next().newPromise();
final Promise<Channel> serverPromise = group.next().newPromise();
sc = new ServerBootstrap().group(group).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
SslHandler handler = sslServerCtx.newHandler(ch.alloc());
handler.setCloseNotifyReadTimeoutMillis(closeNotifyReadTimeout);
handler.sslCloseFuture().addListener(new PromiseNotifier<Channel, Future<Channel>>(serverPromise));
handler.handshakeFuture().addListener(new FutureListener<Channel>() {
@Override
public void operationComplete(Future<Channel> future) {
if (!future.isSuccess()) {
// Something bad happened during handshake fail the promise!
serverPromise.tryFailure(future.cause());
}
}
});
ch.pipeline().addLast(handler);
}
}).bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
cc = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
final AtomicBoolean closeSent = new AtomicBoolean();
if (timeout) {
ch.pipeline().addFirst(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (closeSent.get()) {
// Drop data on the floor so we will get a timeout while waiting for the
// close_notify.
ReferenceCountUtil.release(msg);
} else {
super.channelRead(ctx, msg);
}
}
});
}
SslHandler handler = sslClientCtx.newHandler(ch.alloc());
handler.setCloseNotifyReadTimeoutMillis(closeNotifyReadTimeout);
handler.sslCloseFuture().addListener(new PromiseNotifier<Channel, Future<Channel>>(clientPromise));
handler.handshakeFuture().addListener(new FutureListener<Channel>() {
@Override
public void operationComplete(Future<Channel> future) {
if (future.isSuccess()) {
closeSent.compareAndSet(false, true);
future.getNow().close();
} else {
// Something bad happened during handshake fail the promise!
clientPromise.tryFailure(future.cause());
}
}
});
ch.pipeline().addLast(handler);
}
}).connect(sc.localAddress()).syncUninterruptibly().channel();
serverPromise.awaitUninterruptibly();
clientPromise.awaitUninterruptibly();
// Server always received the close_notify as the client triggers the close sequence.
assertTrue(serverPromise.isSuccess());
// Depending on if we wait for the response or not the promise will be failed or not.
if (closeNotifyReadTimeout > 0 && !timeout) {
assertTrue(clientPromise.isSuccess());
} else {
assertFalse(clientPromise.isSuccess());
}
} finally {
if (cc != null) {
cc.close().syncUninterruptibly();
}
if (sc != null) {
sc.close().syncUninterruptibly();
}
group.shutdownGracefully();
ReferenceCountUtil.release(sslServerCtx);
ReferenceCountUtil.release(sslClientCtx);
}
}
use of io.netty.util.concurrent.PromiseNotifier in project cassandra by apache.
the class OutboundConnection method requestConnect.
/**
* Returns a future that completes when we are _maybe_ reconnected.
*
* The connection attempt is guaranteed to have completed (successfully or not) by the time any listeners are invoked,
* so if a reconnection attempt is needed, it is already scheduled.
*/
private Future<?> requestConnect() {
// we may race with updates to this variable, but this is fine, since we only guarantee that we see a value
// that did at some point represent an active connection attempt - if it is stale, it will have been completed
// and the caller can retry (or utilise the successfully established connection)
{
State state = this.state;
if (state.isConnecting())
return state.connecting().attempt;
}
Promise<Object> promise = AsyncPromise.uncancellable(eventLoop);
runOnEventLoop(() -> {
if (// never going to connect
isClosed()) {
promise.tryFailure(new ClosedChannelException());
} else if (// already connected
state.isEstablished() && state.established().isConnected()) {
promise.trySuccess(null);
} else {
if (state.isEstablished())
setDisconnected();
if (!state.isConnecting()) {
assert eventLoop.inEventLoop();
assert !isConnected();
initiate().addListener(new PromiseNotifier<>(promise));
} else {
state.connecting().attempt.addListener(new PromiseNotifier<>(promise));
}
}
});
return promise;
}
use of io.netty.util.concurrent.PromiseNotifier in project netty by netty.
the class WebSocketProtocolHandler method write.
@Override
public void write(final ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (closeSent != null) {
ReferenceCountUtil.release(msg);
promise.setFailure(new ClosedChannelException());
} else if (msg instanceof CloseWebSocketFrame) {
closeSent(promise.unvoid());
ctx.write(msg).addListener(new PromiseNotifier<Void, ChannelFuture>(false, closeSent));
} else {
ctx.write(msg, promise);
}
}
Aggregations