Ext service integration support for Netconf SSH client
[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.controller.config.threadpool.ScheduledThreadPool;
18 import org.opendaylight.controller.config.threadpool.ThreadPool;
19 import org.opendaylight.mdsal.binding.api.DataBroker;
20 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
21 import org.opendaylight.netconf.callhome.protocol.CallHomeChannelActivator;
22 import org.opendaylight.netconf.callhome.protocol.CallHomeNetconfSubsystemListener;
23 import org.opendaylight.netconf.callhome.protocol.CallHomeProtocolSessionContext;
24 import org.opendaylight.netconf.client.NetconfClientDispatcher;
25 import org.opendaylight.netconf.client.NetconfClientSession;
26 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
27 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
28 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
29 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
30 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
31 import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
33 import org.osgi.service.component.annotations.Activate;
34 import org.osgi.service.component.annotations.Component;
35 import org.osgi.service.component.annotations.Reference;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 @Component(service = { CallHomeMountDispatcher.class, CallHomeNetconfSubsystemListener.class }, immediate = true)
40 // Non-final for testing
41 public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHomeNetconfSubsystemListener {
42     private static final Logger LOG = LoggerFactory.getLogger(CallHomeMountDispatcher.class);
43
44     private final CallHomeMountSessionManager sessionManager = new CallHomeMountSessionManager();
45     private final String topologyId;
46     private final EventExecutor eventExecutor;
47     private final ScheduledThreadPool keepaliveExecutor;
48     private final ThreadPool processingExecutor;
49     private final SchemaResourceManager schemaRepositoryProvider;
50     private final DataBroker dataBroker;
51     private final DOMMountPointService mountService;
52     private final NetconfClientConfigurationBuilderFactory builderFactory;
53
54     protected CallHomeTopology topology;
55
56     private final DeviceActionFactory deviceActionFactory;
57     private final BaseNetconfSchemas baseSchemas;
58
59
60     public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor,
61             final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
62             final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas,
63             final DataBroker dataBroker, final DOMMountPointService mountService,
64             final NetconfClientConfigurationBuilderFactory builderFactory) {
65         this(topologyId, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider, baseSchemas,
66             dataBroker, mountService, builderFactory, null);
67     }
68
69     @Activate
70     public CallHomeMountDispatcher(
71             @Reference(target = "(type=global-event-executor)") final EventExecutor eventExecutor,
72             @Reference(target = "(type=global-netconf-ssh-scheduled-executor)")
73                 final ScheduledThreadPool keepaliveExecutor,
74             @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingExecutor,
75             @Reference final SchemaResourceManager schemaRepositoryProvider,
76             @Reference final BaseNetconfSchemas baseSchemas, @Reference final DataBroker dataBroker,
77             @Reference final DOMMountPointService mountService,
78             @Reference final NetconfClientConfigurationBuilderFactory builderFactory,
79             @Reference final DeviceActionFactory deviceActionFactory) {
80         this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, eventExecutor, keepaliveExecutor, processingExecutor,
81             schemaRepositoryProvider, baseSchemas, dataBroker, mountService, builderFactory, deviceActionFactory);
82     }
83
84     public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor,
85             final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
86             final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas,
87             final DataBroker dataBroker, final DOMMountPointService mountService,
88             final NetconfClientConfigurationBuilderFactory builderFactory,
89             final DeviceActionFactory deviceActionFactory) {
90         this.topologyId = topologyId;
91         this.eventExecutor = eventExecutor;
92         this.keepaliveExecutor = keepaliveExecutor;
93         this.processingExecutor = processingExecutor;
94         this.schemaRepositoryProvider = schemaRepositoryProvider;
95         this.deviceActionFactory = deviceActionFactory;
96         this.baseSchemas = requireNonNull(baseSchemas);
97         this.dataBroker = dataBroker;
98         this.mountService = mountService;
99         this.builderFactory = requireNonNull(builderFactory);
100     }
101
102     @Deprecated
103     @Override
104     public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
105         return activateChannel(clientConfiguration);
106     }
107
108     private Future<NetconfClientSession> activateChannel(final NetconfClientConfiguration conf) {
109         final InetSocketAddress remoteAddr = conf.getAddress();
110         final CallHomeMountSessionContext context = sessionManager().getByAddress(remoteAddr);
111         LOG.info("Activating NETCONF channel for ip {} device context {}", remoteAddr, context);
112         return context == null ? new FailedFuture<>(eventExecutor, new NullPointerException())
113             : context.activateNetconfChannel(conf.getSessionListener());
114     }
115
116     @Override
117     public void onNetconfSubsystemOpened(final CallHomeProtocolSessionContext session,
118                                          final CallHomeChannelActivator activator) {
119         final var deviceContext = sessionManager().createSession(session, activator, device -> {
120             final var nodeId = device.getId();
121             LOG.info("Removing {} from Netconf Topology.", nodeId);
122             topology.disconnectNode(nodeId);
123         });
124         if (deviceContext != null) {
125             final Node configNode = deviceContext.getConfigNode();
126             LOG.info("Provisioning fake config {}", configNode);
127             topology.connectNode(configNode);
128         }
129     }
130
131     @VisibleForTesting
132     void createTopology() {
133         topology = new CallHomeTopology(topologyId, this, eventExecutor, keepaliveExecutor, processingExecutor,
134                 schemaRepositoryProvider, dataBroker, mountService, builderFactory, baseSchemas, deviceActionFactory);
135     }
136
137     @VisibleForTesting
138     CallHomeMountSessionManager sessionManager() {
139         return sessionManager;
140     }
141 }