2 * Copyright (c) 2016 Brocade Communication Systems 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.callhome.mount;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import io.netty.util.concurrent.EventExecutor;
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.NetconfClientFactory;
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;
39 @Component(service = { CallHomeMountFactory.class, CallHomeNetconfSubsystemListener.class }, immediate = true)
40 // Non-final for testing
41 public class CallHomeMountFactory implements NetconfClientFactory, CallHomeNetconfSubsystemListener {
42 private static final Logger LOG = LoggerFactory.getLogger(CallHomeMountFactory.class);
44 private final CallHomeMountSessionManager sessionManager = new CallHomeMountSessionManager();
45 private final String topologyId;
46 private final EventExecutor eventExecutor;
47 private final ScheduledThreadPool scheduledThreadPool;
48 private final ThreadPool processingThreadPool;
49 private final SchemaResourceManager schemaRepositoryProvider;
50 private final DataBroker dataBroker;
51 private final DOMMountPointService mountService;
52 private final NetconfClientConfigurationBuilderFactory builderFactory;
54 protected CallHomeTopology topology;
56 private final DeviceActionFactory deviceActionFactory;
57 private final BaseNetconfSchemas baseSchemas;
60 public CallHomeMountFactory(final String topologyId, final EventExecutor eventExecutor,
61 final ScheduledThreadPool scheduledThreadPool, final ThreadPool processingThreadPool,
62 final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas,
63 final DataBroker dataBroker, final DOMMountPointService mountService,
64 final NetconfClientConfigurationBuilderFactory builderFactory) {
65 this(topologyId, eventExecutor, scheduledThreadPool, processingThreadPool, schemaRepositoryProvider,
66 baseSchemas, dataBroker, mountService, builderFactory, null);
70 public CallHomeMountFactory(
71 @Reference(target = "(type=global-event-executor)") final EventExecutor eventExecutor,
72 @Reference(target = "(type=global-netconf-ssh-scheduled-executor)")
73 final ScheduledThreadPool scheduledThreadPool,
74 @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingThreadPool,
75 @Reference final SchemaResourceManager schemaRepositoryProvider,
76 @Reference final BaseNetconfSchemas baseSchemas, @Reference final DataBroker dataBroker,
77 @Reference final DOMMountPointService mountService,
78 @Reference(target = "(type=legacy)") final NetconfClientConfigurationBuilderFactory builderFactory,
79 @Reference final DeviceActionFactory deviceActionFactory) {
80 this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, eventExecutor, scheduledThreadPool, processingThreadPool,
81 schemaRepositoryProvider, baseSchemas, dataBroker, mountService, builderFactory, deviceActionFactory);
84 public CallHomeMountFactory(final String topologyId, final EventExecutor eventExecutor,
85 final ScheduledThreadPool scheduledThreadPool, final ThreadPool processingThreadPool,
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.scheduledThreadPool = scheduledThreadPool;
93 this.processingThreadPool = processingThreadPool;
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);
104 public ListenableFuture<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
105 return activateChannel(clientConfiguration);
108 private ListenableFuture<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 ? Futures.immediateFailedFuture(new NullPointerException("context is null"))
113 : context.activateNetconfChannel(conf.getSessionListener());
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);
124 if (deviceContext != null) {
125 final Node configNode = deviceContext.getConfigNode();
126 LOG.info("Provisioning fake config {}", configNode);
127 topology.connectNode(configNode);
132 void createTopology() {
133 topology = new CallHomeTopology(topologyId, this, eventExecutor, scheduledThreadPool, processingThreadPool,
134 schemaRepositoryProvider, dataBroker, mountService, builderFactory, baseSchemas, deviceActionFactory);
138 CallHomeMountSessionManager sessionManager() {
139 return sessionManager;
143 public void close() throws Exception {