Add AbstractClientChannelInitializer
[netconf.git] / netconf / netconf-client / src / main / java / org / opendaylight / netconf / client / TlsClientChannelInitializer.java
1 /*
2  * Copyright (c) 2018 ZTE Corporation. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.client;
9
10 import io.netty.channel.Channel;
11 import io.netty.channel.ChannelHandlerContext;
12 import io.netty.channel.ChannelInboundHandlerAdapter;
13 import io.netty.util.concurrent.Promise;
14
15 public final class TlsClientChannelInitializer extends AbstractClientChannelInitializer {
16     public static final String CHANNEL_ACTIVE_SENTRY = "channelActiveSentry";
17
18     private final SslHandlerFactory sslHandlerFactory;
19
20     public TlsClientChannelInitializer(final SslHandlerFactory sslHandlerFactory,
21                                        final NetconfClientSessionNegotiatorFactory negotiatorFactory,
22                                        final NetconfClientSessionListener sessionListener) {
23         super(negotiatorFactory, sessionListener);
24         this.sslHandlerFactory = sslHandlerFactory;
25     }
26
27     @Override
28     public void initialize(final Channel ch, final Promise<NetconfClientSession> promise) {
29         // When ssl handshake fails due to the certificate mismatch, the connection will try again,
30         // then we have a chance to create a new SslHandler using the latest certificates with the
31         // help of the sentry. We will replace the sentry with the new SslHandler once the channel
32         // is active.
33         ch.pipeline().addFirst(CHANNEL_ACTIVE_SENTRY, new ChannelActiveSentry(sslHandlerFactory));
34         super.initialize(ch, promise);
35     }
36
37     private static final class ChannelActiveSentry extends ChannelInboundHandlerAdapter {
38         private final SslHandlerFactory sslHandlerFactory;
39
40         ChannelActiveSentry(final SslHandlerFactory sslHandlerFactory) {
41             this.sslHandlerFactory = sslHandlerFactory;
42         }
43
44         @Override
45         public void channelActive(final ChannelHandlerContext ctx) {
46             final var sslHandler = sslHandlerFactory.createSslHandler();
47             ctx.pipeline().replace(this, "sslHandler", sslHandler).fireChannelActive();
48         }
49     }
50 }