Teach netconf-client abount maximum incoming chunk size
[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.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;
30
31 @Singleton
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);
37
38     private final Timer timer;
39
40     @Inject
41     @Activate
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);
47     }
48
49     protected final Timer getTimer() {
50         return timer;
51     }
52
53     @Override
54     public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
55         switch (clientConfiguration.getProtocol()) {
56             case TCP:
57                 return createTcpClient(clientConfiguration);
58             case SSH:
59                 return createSshClient(clientConfiguration);
60             case TLS:
61                 return createTlsClient(clientConfiguration);
62             default:
63                 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
64         }
65     }
66
67     @Override
68     public ReconnectFuture createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
69         switch (clientConfiguration.getProtocol()) {
70             case TCP:
71                 return createReconnectingTcpClient(clientConfiguration);
72             case SSH:
73                 return createReconnectingSshClient(clientConfiguration);
74             case TLS:
75                 return createReconnectingTlsClient(clientConfiguration);
76             default:
77                 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
78         }
79     }
80
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));
86     }
87
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());
94
95         return super.createReconnectingClient(currentConfiguration.getAddress(),
96                 currentConfiguration.getConnectStrategyFactory(), init::initialize);
97     }
98
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));
105     }
106
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());
113
114         return super.createReconnectingClient(currentConfiguration.getAddress(),
115                 currentConfiguration.getConnectStrategyFactory(), init::initialize);
116     }
117
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));
124     }
125
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());
132
133         return super.createReconnectingClient(currentConfiguration.getAddress(),
134                 currentConfiguration.getConnectStrategyFactory(), init::initialize);
135     }
136
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());
142         }
143
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());
149         }
150         return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
151             cfg.getConnectionTimeoutMillis(), stringCapabilities);
152     }
153 }