Rework createReconnectingClient()
[netconf.git] / netconf / 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 io.netty.util.concurrent.EventExecutor;
13 import io.netty.util.concurrent.FailedFuture;
14 import io.netty.util.concurrent.Future;
15 import java.net.InetSocketAddress;
16 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
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.mount.CallHomeMountSessionContext.CloseCallback;
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.nettyutil.ReconnectFuture;
30 import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory;
31 import org.opendaylight.netconf.sal.connect.api.SchemaResourceManager;
32 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseNetconfSchemas;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 public class CallHomeMountDispatcher implements NetconfClientDispatcher, CallHomeNetconfSubsystemListener {
39
40     private static final Logger LOG = LoggerFactory.getLogger(CallHomeMountDispatcher.class);
41
42     private final String topologyId;
43     private final EventExecutor eventExecutor;
44     private final ScheduledThreadPool keepaliveExecutor;
45     private final ThreadPool processingExecutor;
46     private final SchemaResourceManager schemaRepositoryProvider;
47     private final CallHomeMountSessionManager sessionManager;
48     private final DataBroker dataBroker;
49     private final DOMMountPointService mountService;
50     private final AAAEncryptionService encryptionService;
51
52     protected CallHomeTopology topology;
53
54     private final CloseCallback onCloseHandler = deviceContext -> {
55         LOG.info("Removing {} from Netconf Topology.", deviceContext.getId());
56         topology.disconnectNode(deviceContext.getId());
57     };
58
59     private final DeviceActionFactory deviceActionFactory;
60     private final BaseNetconfSchemas baseSchemas;
61
62     public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor,
63                                    final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
64                                    final SchemaResourceManager schemaRepositoryProvider,
65                                    final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker,
66                                    final DOMMountPointService mountService,
67                                    final AAAEncryptionService encryptionService) {
68         this(topologyId, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider, baseSchemas,
69             dataBroker, mountService, encryptionService, null);
70     }
71
72     public CallHomeMountDispatcher(final String topologyId, final EventExecutor eventExecutor,
73             final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
74             final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas,
75             final DataBroker dataBroker, final DOMMountPointService mountService,
76             final AAAEncryptionService encryptionService, final DeviceActionFactory deviceActionFactory) {
77         this.topologyId = topologyId;
78         this.eventExecutor = eventExecutor;
79         this.keepaliveExecutor = keepaliveExecutor;
80         this.processingExecutor = processingExecutor;
81         this.schemaRepositoryProvider = schemaRepositoryProvider;
82         this.deviceActionFactory = deviceActionFactory;
83         this.sessionManager = new CallHomeMountSessionManager();
84         this.baseSchemas = requireNonNull(baseSchemas);
85         this.dataBroker = dataBroker;
86         this.mountService = mountService;
87         this.encryptionService = encryptionService;
88     }
89
90     @Override
91     public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
92         return activateChannel(clientConfiguration);
93     }
94
95     @Override
96     public ReconnectFuture createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
97         return new SingleReconnectFuture(eventExecutor, activateChannel(clientConfiguration));
98     }
99
100     private Future<NetconfClientSession> activateChannel(final NetconfClientConfiguration conf) {
101         final InetSocketAddress remoteAddr = conf.getAddress();
102         final CallHomeMountSessionContext context = getSessionManager().getByAddress(remoteAddr);
103         LOG.info("Activating NETCONF channel for ip {} device context {}", remoteAddr, context);
104         return context == null ? new FailedFuture<>(eventExecutor, new NullPointerException())
105             : context.activateNetconfChannel(conf.getSessionListener());
106     }
107
108     void createTopology() {
109         this.topology = new CallHomeTopology(topologyId, this, eventExecutor, keepaliveExecutor, processingExecutor,
110                 schemaRepositoryProvider, dataBroker, mountService, encryptionService, baseSchemas,
111                 deviceActionFactory);
112     }
113
114     @Override
115     public void onNetconfSubsystemOpened(final CallHomeProtocolSessionContext session,
116                                          final CallHomeChannelActivator activator) {
117         final CallHomeMountSessionContext deviceContext =
118                 getSessionManager().createSession(session, activator, onCloseHandler);
119         if (deviceContext != null) {
120             final NodeId nodeId = deviceContext.getId();
121             final Node configNode = deviceContext.getConfigNode();
122             LOG.info("Provisioning fake config {}", configNode);
123             topology.connectNode(nodeId, configNode);
124         }
125     }
126
127     public CallHomeMountSessionManager getSessionManager() {
128         return sessionManager;
129     }
130 }