861d3e217c5af0e80db4b3d6f9b5a5c631ba69f1
[netconf.git] / apps / callhome-provider / src / main / java / org / opendaylight / netconf / callhome / mount / CallHomeMountDispatcher.java
1 /*
2  * Copyright (c) 2016 Brocade Communication Systems 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.callhome.mount;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.VisibleForTesting;
13 import io.netty.util.concurrent.EventExecutor;
14 import io.netty.util.concurrent.FailedFuture;
15 import io.netty.util.concurrent.Future;
16 import java.net.InetSocketAddress;
17 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
18 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
19 import org.opendaylight.controller.config.threadpool.ThreadPool;
20 import org.opendaylight.mdsal.binding.api.DataBroker;
21 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
22 import org.opendaylight.netconf.callhome.protocol.CallHomeChannelActivator;
23 import org.opendaylight.netconf.callhome.protocol.CallHomeNetconfSubsystemListener;
24 import org.opendaylight.netconf.callhome.protocol.CallHomeProtocolSessionContext;
25 import org.opendaylight.netconf.client.NetconfClientDispatcher;
26 import org.opendaylight.netconf.client.NetconfClientSession;
27 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
28 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
29 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
30 import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
31 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
32 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
33 import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider;
34 import org.opendaylight.netconf.nettyutil.ReconnectFuture;
35 import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
38 import org.osgi.service.component.annotations.Activate;
39 import org.osgi.service.component.annotations.Component;
40 import org.osgi.service.component.annotations.Reference;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 @Component(service = { CallHomeMountDispatcher.class, CallHomeNetconfSubsystemListener.class }, immediate = true)
45 // Non-final for testing
46 public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHomeNetconfSubsystemListener {
47     private static final Logger LOG = LoggerFactory.getLogger(CallHomeMountDispatcher.class);
48
49     private final CallHomeMountSessionManager sessionManager = new CallHomeMountSessionManager();
50     private final String topologyId;
51     private final EventExecutor eventExecutor;
52     private final ScheduledThreadPool keepaliveExecutor;
53     private final ThreadPool processingExecutor;
54     private final SchemaResourceManager schemaRepositoryProvider;
55     private final DataBroker dataBroker;
56     private final DOMMountPointService mountService;
57     private final AAAEncryptionService encryptionService;
58     private final CredentialProvider credentialProvider;
59     private final SslHandlerFactoryProvider sslHandlerFactoryProvider;
60
61     protected CallHomeTopology topology;
62
63     private final DeviceActionFactory deviceActionFactory;
64     private final BaseNetconfSchemas baseSchemas;
65
66
67     public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor,
68             final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
69             final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas,
70             final DataBroker dataBroker, final DOMMountPointService mountService,
71             final AAAEncryptionService encryptionService, final CredentialProvider credentialProvider,
72             final SslHandlerFactoryProvider sslHandlerFactoryProvider) {
73         this(topologyId, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider, baseSchemas,
74             dataBroker, mountService, encryptionService, credentialProvider, sslHandlerFactoryProvider, null);
75     }
76
77     @Activate
78     public CallHomeMountDispatcher(
79             @Reference(target = "(type=global-event-executor)") final EventExecutor eventExecutor,
80             @Reference(target = "(type=global-netconf-ssh-scheduled-executor)")
81                 final ScheduledThreadPool keepaliveExecutor,
82             @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingExecutor,
83             @Reference final SchemaResourceManager schemaRepositoryProvider,
84             @Reference final BaseNetconfSchemas baseSchemas, @Reference final DataBroker dataBroker,
85             @Reference final DOMMountPointService mountService, @Reference final AAAEncryptionService encryptionService,
86             @Reference final CredentialProvider credentialProvider,
87             @Reference final SslHandlerFactoryProvider sslHandlerFactoryProvider,
88             @Reference final DeviceActionFactory deviceActionFactory) {
89         this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, eventExecutor, keepaliveExecutor, processingExecutor,
90             schemaRepositoryProvider, baseSchemas, dataBroker, mountService, encryptionService, credentialProvider,
91             sslHandlerFactoryProvider, deviceActionFactory);
92     }
93
94     public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor,
95             final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
96             final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas,
97             final DataBroker dataBroker, final DOMMountPointService mountService,
98             final AAAEncryptionService encryptionService, final CredentialProvider credentialProvider,
99             final SslHandlerFactoryProvider sslHandlerFactoryProvider, final DeviceActionFactory deviceActionFactory) {
100         this.topologyId = topologyId;
101         this.eventExecutor = eventExecutor;
102         this.keepaliveExecutor = keepaliveExecutor;
103         this.processingExecutor = processingExecutor;
104         this.schemaRepositoryProvider = schemaRepositoryProvider;
105         this.deviceActionFactory = deviceActionFactory;
106         this.baseSchemas = requireNonNull(baseSchemas);
107         this.dataBroker = dataBroker;
108         this.mountService = mountService;
109         this.encryptionService = encryptionService;
110         this.credentialProvider = requireNonNull(credentialProvider);
111         this.sslHandlerFactoryProvider = requireNonNull(sslHandlerFactoryProvider);
112     }
113
114     @Override
115     public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
116         return activateChannel(clientConfiguration);
117     }
118
119     @Override
120     public ReconnectFuture createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
121         return new SingleReconnectFuture(eventExecutor, activateChannel(clientConfiguration));
122     }
123
124     private Future<NetconfClientSession> activateChannel(final NetconfClientConfiguration conf) {
125         final InetSocketAddress remoteAddr = conf.getAddress();
126         final CallHomeMountSessionContext context = sessionManager().getByAddress(remoteAddr);
127         LOG.info("Activating NETCONF channel for ip {} device context {}", remoteAddr, context);
128         return context == null ? new FailedFuture<>(eventExecutor, new NullPointerException())
129             : context.activateNetconfChannel(conf.getSessionListener());
130     }
131
132     @Override
133     public void onNetconfSubsystemOpened(final CallHomeProtocolSessionContext session,
134                                          final CallHomeChannelActivator activator) {
135         final var deviceContext = sessionManager().createSession(session, activator, device -> {
136             final var nodeId = device.getId();
137             LOG.info("Removing {} from Netconf Topology.", nodeId);
138             topology.disconnectNode(nodeId);
139         });
140         if (deviceContext != null) {
141             final NodeId nodeId = deviceContext.getId();
142             final Node configNode = deviceContext.getConfigNode();
143             LOG.info("Provisioning fake config {}", configNode);
144             topology.connectNode(nodeId, configNode);
145         }
146     }
147
148     @VisibleForTesting
149     void createTopology() {
150         topology = new CallHomeTopology(topologyId, this, eventExecutor, keepaliveExecutor, processingExecutor,
151                 schemaRepositoryProvider, dataBroker, mountService, encryptionService, baseSchemas,
152                 deviceActionFactory, credentialProvider, sslHandlerFactoryProvider);
153     }
154
155     @VisibleForTesting
156     CallHomeMountSessionManager sessionManager() {
157         return sessionManager;
158     }
159 }