2 * Copyright (c) 2023 PANTHEON.tech s.r.o. 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 com.google.common.collect.ImmutableSet;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import javax.annotation.PreDestroy;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.opendaylight.netconf.api.TransportConstants;
21 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
22 import org.opendaylight.netconf.common.NetconfTimer;
23 import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
24 import org.opendaylight.netconf.transport.ssh.SSHTransportStackFactory;
25 import org.opendaylight.netconf.transport.tcp.TCPClient;
26 import org.opendaylight.netconf.transport.tls.FixedSslHandlerFactory;
27 import org.opendaylight.netconf.transport.tls.TLSClient;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
29 import org.osgi.service.component.annotations.Activate;
30 import org.osgi.service.component.annotations.Component;
31 import org.osgi.service.component.annotations.Deactivate;
32 import org.osgi.service.component.annotations.Reference;
35 @Component(service = NetconfClientFactory.class)
36 public final class NetconfClientFactoryImpl implements NetconfClientFactory {
37 private final SSHTransportStackFactory factory;
38 private final NetconfTimer timer;
40 public NetconfClientFactoryImpl(final NetconfTimer timer, final SSHTransportStackFactory factory) {
41 this.timer = requireNonNull(timer);
42 this.factory = requireNonNull(factory);
47 public NetconfClientFactoryImpl(@Reference final NetconfTimer timer) {
48 // FIXME: make factory component configurable for OSGi
49 this(timer, new SSHTransportStackFactory("odl-netconf-client", 0));
60 public ListenableFuture<NetconfClientSession> createClient(final NetconfClientConfiguration configuration)
61 throws UnsupportedConfigurationException {
62 final var sessionListener = configuration.getSessionListener();
63 final var transportListener = new ClientTransportChannelListener(new ClientChannelInitializer(
64 createNegotiatorFactory(configuration), () -> sessionListener));
66 final var stackFuture = switch (configuration.getProtocol()) {
67 case SSH -> factory.connectClient(TransportConstants.SSH_SUBSYSTEM, transportListener,
68 configuration.getTcpParameters(), configuration.getSshParameters(), configuration.getSshConfigurator());
69 case TCP -> TCPClient.connect(transportListener, factory.newBootstrap(), configuration.getTcpParameters());
71 var handlerFactory = configuration.getSslHandlerFactory();
72 if (handlerFactory == null) {
73 handlerFactory = new FixedSslHandlerFactory(configuration.getTlsParameters());
75 yield TLSClient.connect(transportListener, factory.newBootstrap(), configuration.getTcpParameters(),
79 Futures.addCallback(stackFuture, transportListener, MoreExecutors.directExecutor());
81 return transportListener.sessionFuture();
84 private @NonNull NetconfClientSessionNegotiatorFactory createNegotiatorFactory(
85 final NetconfClientConfiguration configuration) {
86 final var capabilities = configuration.getOdlHelloCapabilities();
87 if (capabilities == null || capabilities.isEmpty()) {
88 return new NetconfClientSessionNegotiatorFactory(timer, configuration.getAdditionalHeader(),
89 configuration.getConnectionTimeoutMillis(), configuration.getMaximumIncomingChunkSize());
91 final var stringCapabilities = capabilities.stream().map(Uri::getValue)
92 .collect(ImmutableSet.toImmutableSet());
93 return new NetconfClientSessionNegotiatorFactory(timer, configuration.getAdditionalHeader(),
94 configuration.getConnectionTimeoutMillis(), stringCapabilities);