import io.netty.handler.ssl.SslHandler;
import io.netty.util.Timeout;
import io.netty.util.Timer;
+import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.Promise;
import java.util.concurrent.TimeUnit;
import org.checkerframework.checker.index.qual.NonNegative;
private void start() {
LOG.debug("Session negotiation started with hello message {} on channel {}", localHello, channel);
- channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
+ // Send the message out, but to not run listeners just yet, as we have some more state transitions to go through
+ final var helloFuture = channel.writeAndFlush(localHello);
- sendMessage(localHello);
+ channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
replaceHelloMessageOutboundHandler();
timeoutTask = timer.newTimeout(unused -> channel.eventLoop().execute(this::timeoutExpired),
connectionTimeoutMillis, TimeUnit.MILLISECONDS);
}
+
+ // State transition completed, now run any additional processing
+ helloFuture.addListener(this::onHelloWriteComplete);
+ }
+
+ private void onHelloWriteComplete(final Future<?> future) {
+ final var cause = future.cause();
+ if (cause != null) {
+ LOG.info("Failed to send message {} on channel {}", localHello, channel, cause);
+ negotiationFailed(cause);
+ } else {
+ LOG.trace("Message {} sent to socket on channel {}", localHello, channel);
+ }
}
private synchronized void timeoutExpired() {
promise.setFailure(cause);
}
- /**
- * Send a message to peer and fail negotiation if it does not reach
- * the peer.
- *
- * @param msg Message which should be sent.
- */
- protected void sendMessage(final NetconfMessage msg) {
- channel.writeAndFlush(msg).addListener(f -> {
- final var cause = f.cause();
- if (cause != null) {
- LOG.info("Failed to send message {} on channel {}", msg, channel, cause);
- negotiationFailed(cause);
- } else {
- LOG.trace("Message {} sent to socket on channel {}", msg, channel);
- }
- });
- }
-
@Override
@SuppressWarnings("checkstyle:illegalCatch")
public final void channelActive(final ChannelHandlerContext ctx) {