2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netconf.client;
10 import static java.util.Objects.requireNonNull;
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;
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.netconf.nettyutil.ReconnectFuture;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
25 import org.osgi.service.component.annotations.Activate;
26 import org.osgi.service.component.annotations.Component;
27 import org.osgi.service.component.annotations.Reference;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 @Component(immediate = true, service = NetconfClientDispatcher.class, property = "type=netconf-client-dispatcher")
33 public class NetconfClientDispatcherImpl
34 extends AbstractNetconfDispatcher<NetconfClientSession, NetconfClientSessionListener>
35 implements NetconfClientDispatcher {
36 private static final Logger LOG = LoggerFactory.getLogger(NetconfClientDispatcherImpl.class);
38 private final Timer timer;
42 public NetconfClientDispatcherImpl(@Reference(target = "(type=global-boss-group)") final EventLoopGroup bossGroup,
43 @Reference(target = "(type=global-worker-group)") final EventLoopGroup workerGroup,
44 @Reference(target = "(type=global-timer)") final Timer timer) {
45 super(bossGroup, workerGroup);
46 this.timer = requireNonNull(timer);
49 protected final Timer getTimer() {
54 public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
55 switch (clientConfiguration.getProtocol()) {
57 return createTcpClient(clientConfiguration);
59 return createSshClient(clientConfiguration);
61 return createTlsClient(clientConfiguration);
63 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
68 public ReconnectFuture createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
69 switch (clientConfiguration.getProtocol()) {
71 return createReconnectingTcpClient(clientConfiguration);
73 return createReconnectingSshClient(clientConfiguration);
75 return createReconnectingTlsClient(clientConfiguration);
77 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
81 private Future<NetconfClientSession> createTcpClient(final NetconfClientConfiguration currentConfiguration) {
82 LOG.debug("Creating TCP client with configuration: {}", currentConfiguration);
83 return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
84 (ch, promise) -> new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
85 currentConfiguration.getSessionListener()).initialize(ch, promise));
88 private ReconnectFuture createReconnectingTcpClient(
89 final NetconfReconnectingClientConfiguration currentConfiguration) {
90 LOG.debug("Creating reconnecting TCP client with configuration: {}", currentConfiguration);
91 final TcpClientChannelInitializer init =
92 new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
93 currentConfiguration.getSessionListener());
95 return super.createReconnectingClient(currentConfiguration.getAddress(),
96 currentConfiguration.getConnectStrategyFactory(), init::initialize);
99 private Future<NetconfClientSession> createSshClient(final NetconfClientConfiguration currentConfiguration) {
100 LOG.debug("Creating SSH client with configuration: {}", currentConfiguration);
101 return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
102 (ch, sessionPromise) -> new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
103 getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(),
104 currentConfiguration.getSshClient()).initialize(ch, sessionPromise));
107 private ReconnectFuture createReconnectingSshClient(
108 final NetconfReconnectingClientConfiguration currentConfiguration) {
109 LOG.debug("Creating reconnecting SSH client with configuration: {}", currentConfiguration);
110 final SshClientChannelInitializer init = new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
111 getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(),
112 currentConfiguration.getSshClient());
114 return super.createReconnectingClient(currentConfiguration.getAddress(),
115 currentConfiguration.getConnectStrategyFactory(), init::initialize);
118 private Future<NetconfClientSession> createTlsClient(final NetconfClientConfiguration currentConfiguration) {
119 LOG.debug("Creating TLS client with configuration: {}", currentConfiguration);
120 return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
121 (ch, sessionPromise) -> new TlsClientChannelInitializer(currentConfiguration.getSslHandlerFactory(),
122 getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
123 .initialize(ch, sessionPromise));
126 private ReconnectFuture createReconnectingTlsClient(
127 final NetconfReconnectingClientConfiguration currentConfiguration) {
128 LOG.debug("Creating reconnecting TLS client with configuration: {}", currentConfiguration);
129 final TlsClientChannelInitializer init = new TlsClientChannelInitializer(
130 currentConfiguration.getSslHandlerFactory(), getNegotiatorFactory(currentConfiguration),
131 currentConfiguration.getSessionListener());
133 return super.createReconnectingClient(currentConfiguration.getAddress(),
134 currentConfiguration.getConnectStrategyFactory(), init::initialize);
137 protected NetconfClientSessionNegotiatorFactory getNegotiatorFactory(final NetconfClientConfiguration cfg) {
138 final List<Uri> odlHelloCapabilities = cfg.getOdlHelloCapabilities();
139 if (odlHelloCapabilities == null || odlHelloCapabilities.isEmpty()) {
140 return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
141 cfg.getConnectionTimeoutMillis(), cfg.getMaximumIncomingChunkSize());
144 // LinkedHashSet since perhaps the device cares about order of hello message capabilities.
145 // This allows user control of the order while complying with the existing interface.
146 final Set<String> stringCapabilities = new LinkedHashSet<>();
147 for (final Uri uri : odlHelloCapabilities) {
148 stringCapabilities.add(uri.getValue());
150 return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
151 cfg.getConnectionTimeoutMillis(), stringCapabilities);