Convert netconf-client to OSGi DS
[netconf.git] / netconf / netconf-client / src / main / java / org / opendaylight / netconf / client / NetconfClientDispatcherImpl.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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 static java.util.Objects.requireNonNull;
11
12 import io.netty.channel.EventLoopGroup;
13 import io.netty.util.Timer;
14 import io.netty.util.concurrent.Future;
15 import java.util.LinkedHashSet;
16 import java.util.List;
17 import java.util.Set;
18 import javax.inject.Inject;
19 import javax.inject.Singleton;
20 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
21 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
22 import org.opendaylight.netconf.nettyutil.AbstractNetconfDispatcher;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
24 import org.osgi.service.component.annotations.Activate;
25 import org.osgi.service.component.annotations.Component;
26 import org.osgi.service.component.annotations.Reference;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 @Singleton
31 @Component(immediate = true, service = NetconfClientDispatcher.class, property = "type=netconf-client-dispatcher")
32 public class NetconfClientDispatcherImpl
33         extends AbstractNetconfDispatcher<NetconfClientSession, NetconfClientSessionListener>
34         implements NetconfClientDispatcher {
35     private static final Logger LOG = LoggerFactory.getLogger(NetconfClientDispatcherImpl.class);
36
37     private final Timer timer;
38
39     @Inject
40     @Activate
41     public NetconfClientDispatcherImpl(@Reference(target = "(type=global-boss-group)") final EventLoopGroup bossGroup,
42             @Reference(target = "(type=global-worker-group)") final EventLoopGroup workerGroup,
43             @Reference(target = "(type=global-timer)") final Timer timer) {
44         super(bossGroup, workerGroup);
45         this.timer = requireNonNull(timer);
46     }
47
48     protected final Timer getTimer() {
49         return timer;
50     }
51
52     @Override
53     public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
54         switch (clientConfiguration.getProtocol()) {
55             case TCP:
56                 return createTcpClient(clientConfiguration);
57             case SSH:
58                 return createSshClient(clientConfiguration);
59             case TLS:
60                 return createTlsClient(clientConfiguration);
61             default:
62                 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
63         }
64     }
65
66     @Override
67     public Future<Void> createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
68         switch (clientConfiguration.getProtocol()) {
69             case TCP:
70                 return createReconnectingTcpClient(clientConfiguration);
71             case SSH:
72                 return createReconnectingSshClient(clientConfiguration);
73             case TLS:
74                 return createReconnectingTlsClient(clientConfiguration);
75             default:
76                 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
77         }
78     }
79
80     private Future<NetconfClientSession> createTcpClient(final NetconfClientConfiguration currentConfiguration) {
81         LOG.debug("Creating TCP client with configuration: {}", currentConfiguration);
82         return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
83             (ch, promise) -> new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
84                         currentConfiguration.getSessionListener()).initialize(ch, promise));
85     }
86
87     private Future<Void> createReconnectingTcpClient(
88             final NetconfReconnectingClientConfiguration currentConfiguration) {
89         LOG.debug("Creating reconnecting TCP client with configuration: {}", currentConfiguration);
90         final TcpClientChannelInitializer init =
91                 new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
92                 currentConfiguration.getSessionListener());
93
94         return super.createReconnectingClient(currentConfiguration.getAddress(),
95                 currentConfiguration.getConnectStrategyFactory(), init::initialize);
96     }
97
98     private Future<NetconfClientSession> createSshClient(final NetconfClientConfiguration currentConfiguration) {
99         LOG.debug("Creating SSH client with configuration: {}", currentConfiguration);
100         return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
101             (ch, sessionPromise) -> new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
102                         getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(),
103                         currentConfiguration.getSshClient()).initialize(ch, sessionPromise));
104     }
105
106     private Future<Void> createReconnectingSshClient(
107             final NetconfReconnectingClientConfiguration currentConfiguration) {
108         LOG.debug("Creating reconnecting SSH client with configuration: {}", currentConfiguration);
109         final SshClientChannelInitializer init = new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
110                 getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(),
111                 currentConfiguration.getSshClient());
112
113         return super.createReconnectingClient(currentConfiguration.getAddress(),
114                 currentConfiguration.getConnectStrategyFactory(), init::initialize);
115     }
116
117     private Future<NetconfClientSession> createTlsClient(final NetconfClientConfiguration currentConfiguration) {
118         LOG.debug("Creating TLS client with configuration: {}", currentConfiguration);
119         return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
120             (ch, sessionPromise) -> new TlsClientChannelInitializer(currentConfiguration.getSslHandlerFactory(),
121                     getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
122                     .initialize(ch, sessionPromise));
123     }
124
125     private Future<Void> createReconnectingTlsClient(
126             final NetconfReconnectingClientConfiguration currentConfiguration) {
127         LOG.debug("Creating reconnecting TLS client with configuration: {}", currentConfiguration);
128         final TlsClientChannelInitializer init = new TlsClientChannelInitializer(
129                 currentConfiguration.getSslHandlerFactory(), getNegotiatorFactory(currentConfiguration),
130                 currentConfiguration.getSessionListener());
131
132         return super.createReconnectingClient(currentConfiguration.getAddress(),
133                 currentConfiguration.getConnectStrategyFactory(), init::initialize);
134     }
135
136     protected NetconfClientSessionNegotiatorFactory getNegotiatorFactory(final NetconfClientConfiguration cfg) {
137         final List<Uri> odlHelloCapabilities = cfg.getOdlHelloCapabilities();
138         if (odlHelloCapabilities == null || odlHelloCapabilities.isEmpty()) {
139             return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
140                     cfg.getConnectionTimeoutMillis());
141         }
142
143         // LinkedHashSet since perhaps the device cares about order of hello message capabilities.
144         // This allows user control of the order while complying with the existing interface.
145         final Set<String> stringCapabilities = new LinkedHashSet<>();
146         for (final Uri uri : odlHelloCapabilities) {
147             stringCapabilities.add(uri.getValue());
148         }
149         return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
150             cfg.getConnectionTimeoutMillis(), stringCapabilities);
151     }
152 }