blob: 0395deed006976fe00ccbb7e6737193b335678fe [file] [log] [blame]
andreaeb70a942015-10-16 21:34:46 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
andreaeb70a942015-10-16 21:34:46 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yuta HIGUCHIe3ae8212017-04-20 10:18:41 -070017package org.onosproject.netconf.ctl.impl;
andreaeb70a942015-10-16 21:34:46 -070018
Holger Schulz092cbbf2017-08-31 17:52:30 +020019import org.bouncycastle.jce.provider.BouncyCastleProvider;
andreaeb70a942015-10-16 21:34:46 -070020import org.onlab.packet.IpAddress;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030021import org.onosproject.cfg.ComponentConfigService;
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -060022import org.onosproject.net.AnnotationKeys;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070023import org.onosproject.net.Device;
andreaeb70a942015-10-16 21:34:46 -070024import org.onosproject.net.DeviceId;
Sean Condon54d82432017-07-26 22:27:25 +010025import org.onosproject.net.config.NetworkConfigRegistry;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070026import org.onosproject.net.device.DeviceService;
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -060027import org.onosproject.net.key.DeviceKey;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070028import org.onosproject.net.key.DeviceKeyId;
29import org.onosproject.net.key.DeviceKeyService;
30import org.onosproject.net.key.UsernamePassword;
andreaeb70a942015-10-16 21:34:46 -070031import org.onosproject.netconf.NetconfController;
32import org.onosproject.netconf.NetconfDevice;
Andrea Campanella950310c2016-02-12 18:14:38 -080033import org.onosproject.netconf.NetconfDeviceFactory;
andreaeb70a942015-10-16 21:34:46 -070034import org.onosproject.netconf.NetconfDeviceInfo;
35import org.onosproject.netconf.NetconfDeviceListener;
Andrea Campanella2464dc32016-02-17 17:54:53 -080036import org.onosproject.netconf.NetconfDeviceOutputEvent;
37import org.onosproject.netconf.NetconfDeviceOutputEventListener;
Andrea Campanella101417d2015-12-11 17:58:07 -080038import org.onosproject.netconf.NetconfException;
Sean Condon54d82432017-07-26 22:27:25 +010039import org.onosproject.netconf.config.NetconfDeviceConfig;
40import org.onosproject.netconf.config.NetconfSshClientLib;
andreaeb70a942015-10-16 21:34:46 -070041import org.osgi.service.component.ComponentContext;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070042import org.osgi.service.component.annotations.Activate;
43import org.osgi.service.component.annotations.Component;
44import org.osgi.service.component.annotations.Deactivate;
45import org.osgi.service.component.annotations.Modified;
46import org.osgi.service.component.annotations.Reference;
47import org.osgi.service.component.annotations.ReferenceCardinality;
andreaeb70a942015-10-16 21:34:46 -070048import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
50
Holger Schulz092cbbf2017-08-31 17:52:30 +020051import java.security.Security;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070052import java.util.Arrays;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030053import java.util.Dictionary;
andreaeb70a942015-10-16 21:34:46 -070054import java.util.Map;
55import java.util.Set;
56import java.util.concurrent.ConcurrentHashMap;
57import java.util.concurrent.CopyOnWriteArraySet;
Andrea Campanellac3627842017-04-04 18:06:54 +020058import java.util.concurrent.ExecutorService;
59import java.util.concurrent.Executors;
andreaeb70a942015-10-16 21:34:46 -070060
Andreas Papazois4752cfa2016-04-25 14:52:12 +030061import static org.onlab.util.Tools.get;
Sean Condon54d82432017-07-26 22:27:25 +010062import static org.onlab.util.Tools.getIntegerProperty;
Andrea Campanellac3627842017-04-04 18:06:54 +020063import static org.onlab.util.Tools.groupedThreads;
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -070064import static org.onosproject.netconf.ctl.impl.OsgiPropertyConstants.*;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030065
andreaeb70a942015-10-16 21:34:46 -070066/**
67 * The implementation of NetconfController.
68 */
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -070069@Component(immediate = true, service = NetconfController.class,
70 property = {
71 NETCONF_CONNECT_TIMEOUT + ":Integer=" + NETCONF_CONNECT_TIMEOUT_DEFAULT,
72 NETCONF_REPLY_TIMEOUT + ":Integer=" + NETCONF_REPLY_TIMEOUT_DEFAULT,
73 NETCONF_IDLE_TIMEOUT + ":Integer=" + NETCONF_IDLE_TIMEOUT_DEFAULT,
74 SSH_LIBRARY + "=" + SSH_LIBRARY_DEFAULT,
75 })
andreaeb70a942015-10-16 21:34:46 -070076public class NetconfControllerImpl implements NetconfController {
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070077
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -070078 /** Time (in seconds) to wait for a NETCONF connect. */
79 protected static int netconfConnectTimeout = NETCONF_CONNECT_TIMEOUT_DEFAULT;
Sean Condon334ad692016-12-13 17:56:56 +000080
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -070081 /** Time (in seconds) waiting for a NetConf reply. */
82 protected static int netconfReplyTimeout = NETCONF_REPLY_TIMEOUT_DEFAULT;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030083
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -070084 /** Time (in seconds) SSH session will close if no traffic seen. */
85 protected static int netconfIdleTimeout = NETCONF_IDLE_TIMEOUT_DEFAULT;
Sean Condon7347de92017-07-21 12:17:25 +010086
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -070087 /** SSH client library to use. */
88 protected static String sshLibrary = SSH_LIBRARY_DEFAULT;
89
90 protected NetconfSshClientLib sshClientLib = NetconfSshClientLib.APACHE_MINA;
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070091
Ray Milkeyd84f89b2018-08-17 14:54:17 -070092 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Andreas Papazois4752cfa2016-04-25 14:52:12 +030093 protected ComponentConfigService cfgService;
94
Ray Milkeyd84f89b2018-08-17 14:54:17 -070095 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Andrea Campanella7e6200a2016-03-21 09:48:40 -070096 protected DeviceService deviceService;
97
Ray Milkeyd84f89b2018-08-17 14:54:17 -070098 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Andrea Campanella7e6200a2016-03-21 09:48:40 -070099 protected DeviceKeyService deviceKeyService;
andreaeb70a942015-10-16 21:34:46 -0700100
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700101 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Sean Condon54d82432017-07-26 22:27:25 +0100102 protected NetworkConfigRegistry netCfgService;
103
andreaeb70a942015-10-16 21:34:46 -0700104 public static final Logger log = LoggerFactory
105 .getLogger(NetconfControllerImpl.class);
106
Andrea Campanella8b1cb672016-01-25 13:58:58 -0800107 private Map<DeviceId, NetconfDevice> netconfDeviceMap = new ConcurrentHashMap<>();
andreaeb70a942015-10-16 21:34:46 -0700108
Andrea Campanella2464dc32016-02-17 17:54:53 -0800109 private final NetconfDeviceOutputEventListener downListener = new DeviceDownEventListener();
110
andreaeb70a942015-10-16 21:34:46 -0700111 protected Set<NetconfDeviceListener> netconfDeviceListeners = new CopyOnWriteArraySet<>();
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700112 protected NetconfDeviceFactory deviceFactory = DefaultNetconfDevice::new;
andreaeb70a942015-10-16 21:34:46 -0700113
Andrea Campanellac3627842017-04-04 18:06:54 +0200114 protected final ExecutorService executor =
115 Executors.newCachedThreadPool(groupedThreads("onos/netconfdevicecontroller",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700116 "connection-reopen-%d", log));
Andrea Campanellac3627842017-04-04 18:06:54 +0200117
andreaeb70a942015-10-16 21:34:46 -0700118 @Activate
119 public void activate(ComponentContext context) {
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300120 cfgService.registerProperties(getClass());
121 modified(context);
Yuta HIGUCHIe9761742017-09-10 15:10:19 -0700122 Security.addProvider(new BouncyCastleProvider());
andreaeb70a942015-10-16 21:34:46 -0700123 log.info("Started");
124 }
125
126 @Deactivate
127 public void deactivate() {
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700128 netconfDeviceMap.values().forEach(device -> {
129 device.getSession().removeDeviceOutputListener(downListener);
130 device.disconnect();
131 });
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300132 cfgService.unregisterProperties(getClass(), false);
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700133 netconfDeviceListeners.clear();
andreaeb70a942015-10-16 21:34:46 -0700134 netconfDeviceMap.clear();
Holger Schulz092cbbf2017-08-31 17:52:30 +0200135 Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
andreaeb70a942015-10-16 21:34:46 -0700136 log.info("Stopped");
137 }
138
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300139 @Modified
140 public void modified(ComponentContext context) {
141 if (context == null) {
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700142 netconfReplyTimeout = NETCONF_REPLY_TIMEOUT_DEFAULT;
143 netconfConnectTimeout = NETCONF_CONNECT_TIMEOUT_DEFAULT;
144 netconfIdleTimeout = NETCONF_IDLE_TIMEOUT_DEFAULT;
145 sshLibrary = SSH_LIBRARY_DEFAULT;
146 sshClientLib = NetconfSshClientLib.APACHE_MINA;
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300147 log.info("No component configuration");
148 return;
149 }
150
151 Dictionary<?, ?> properties = context.getProperties();
152
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700153 String newSshLibrary;
Sean Condon334ad692016-12-13 17:56:56 +0000154
Sean Condon54d82432017-07-26 22:27:25 +0100155 int newNetconfReplyTimeout = getIntegerProperty(
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700156 properties, NETCONF_REPLY_TIMEOUT, netconfReplyTimeout);
Sean Condon54d82432017-07-26 22:27:25 +0100157 int newNetconfConnectTimeout = getIntegerProperty(
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700158 properties, NETCONF_CONNECT_TIMEOUT, netconfConnectTimeout);
Sean Condon54d82432017-07-26 22:27:25 +0100159 int newNetconfIdleTimeout = getIntegerProperty(
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700160 properties, NETCONF_IDLE_TIMEOUT, netconfIdleTimeout);
Sean Condon334ad692016-12-13 17:56:56 +0000161
Sean Condon54d82432017-07-26 22:27:25 +0100162 newSshLibrary = get(properties, SSH_LIBRARY);
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300163
Sean Condon334ad692016-12-13 17:56:56 +0000164 if (newNetconfConnectTimeout < 0) {
165 log.warn("netconfConnectTimeout is invalid - less than 0");
166 return;
167 } else if (newNetconfReplyTimeout <= 0) {
168 log.warn("netconfReplyTimeout is invalid - 0 or less.");
169 return;
Sean Condon7347de92017-07-21 12:17:25 +0100170 } else if (newNetconfIdleTimeout <= 0) {
171 log.warn("netconfIdleTimeout is invalid - 0 or less.");
172 return;
Sean Condon334ad692016-12-13 17:56:56 +0000173 }
174
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300175 netconfReplyTimeout = newNetconfReplyTimeout;
Sean Condon334ad692016-12-13 17:56:56 +0000176 netconfConnectTimeout = newNetconfConnectTimeout;
Sean Condon7347de92017-07-21 12:17:25 +0100177 netconfIdleTimeout = newNetconfIdleTimeout;
Sean Condon54d82432017-07-26 22:27:25 +0100178 if (newSshLibrary != null) {
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700179 sshLibrary = newSshLibrary;
180 sshClientLib = NetconfSshClientLib.getEnum(newSshLibrary);
Sean Condon54d82432017-07-26 22:27:25 +0100181 }
182 log.info("Settings: {} = {}, {} = {}, {} = {}, {} = {}",
Thomas Vachuska00b5d4f2018-10-30 15:13:20 -0700183 NETCONF_REPLY_TIMEOUT, netconfReplyTimeout,
184 NETCONF_CONNECT_TIMEOUT, netconfConnectTimeout,
185 NETCONF_IDLE_TIMEOUT, netconfIdleTimeout,
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700186 SSH_LIBRARY, sshLibrary);
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300187 }
188
andreaeb70a942015-10-16 21:34:46 -0700189 @Override
190 public void addDeviceListener(NetconfDeviceListener listener) {
191 if (!netconfDeviceListeners.contains(listener)) {
192 netconfDeviceListeners.add(listener);
193 }
194 }
195
196 @Override
197 public void removeDeviceListener(NetconfDeviceListener listener) {
198 netconfDeviceListeners.remove(listener);
199 }
200
201 @Override
202 public NetconfDevice getNetconfDevice(DeviceId deviceInfo) {
203 return netconfDeviceMap.get(deviceInfo);
204 }
205
206 @Override
207 public NetconfDevice getNetconfDevice(IpAddress ip, int port) {
andreaeb70a942015-10-16 21:34:46 -0700208 for (DeviceId info : netconfDeviceMap.keySet()) {
Andrea Campanella57efbb22016-02-11 14:21:41 -0800209 if (info.uri().getSchemeSpecificPart().equals(ip.toString() + ":" + port)) {
andreaeb70a942015-10-16 21:34:46 -0700210 return netconfDeviceMap.get(info);
211 }
212 }
Andrea Campanella1cd641b2015-12-07 17:28:34 -0800213 return null;
andreaeb70a942015-10-16 21:34:46 -0700214 }
215
216 @Override
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700217 public NetconfDevice connectDevice(DeviceId deviceId) throws NetconfException {
Sean Condon54d82432017-07-26 22:27:25 +0100218 NetconfDeviceConfig netCfg = netCfgService.getConfig(
219 deviceId, NetconfDeviceConfig.class);
220 NetconfDeviceInfo deviceInfo = null;
221
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700222 if (netconfDeviceMap.containsKey(deviceId)) {
223 log.debug("Device {} is already present", deviceId);
224 return netconfDeviceMap.get(deviceId);
Sean Condon54d82432017-07-26 22:27:25 +0100225 } else if (netCfg != null) {
226 log.debug("Device {} is present in NetworkConfig", deviceId);
227 deviceInfo = new NetconfDeviceInfo(netCfg);
228
andreaeb70a942015-10-16 21:34:46 -0700229 } else {
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700230 log.debug("Creating NETCONF device {}", deviceId);
231 Device device = deviceService.getDevice(deviceId);
232 String ip;
233 int port;
234 if (device != null) {
235 ip = device.annotations().value("ipaddress");
236 port = Integer.parseInt(device.annotations().value("port"));
237 } else {
238 String[] info = deviceId.toString().split(":");
239 if (info.length == 3) {
240 ip = info[1];
241 port = Integer.parseInt(info[2]);
242 } else {
243 ip = Arrays.asList(info).stream().filter(el -> !el.equals(info[0])
Andrea Campanellac3627842017-04-04 18:06:54 +0200244 && !el.equals(info[info.length - 1]))
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700245 .reduce((t, u) -> t + ":" + u)
246 .get();
247 log.debug("ip v6 {}", ip);
248 port = Integer.parseInt(info[info.length - 1]);
249 }
250 }
251 try {
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -0600252 DeviceKey deviceKey = deviceKeyService.getDeviceKey(
Andrea Campanellac3627842017-04-04 18:06:54 +0200253 DeviceKeyId.deviceKeyId(deviceId.toString()));
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -0600254 if (deviceKey.type() == DeviceKey.Type.USERNAME_PASSWORD) {
255 UsernamePassword usernamepasswd = deviceKey.asUsernamePassword();
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700256
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -0600257 deviceInfo = new NetconfDeviceInfo(usernamepasswd.username(),
Andrea Campanellac3627842017-04-04 18:06:54 +0200258 usernamepasswd.password(),
259 IpAddress.valueOf(ip),
260 port);
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -0600261
262 } else if (deviceKey.type() == DeviceKey.Type.SSL_KEY) {
263 String username = deviceKey.annotations().value(AnnotationKeys.USERNAME);
264 String password = deviceKey.annotations().value(AnnotationKeys.PASSWORD);
Andrea Campanellac3627842017-04-04 18:06:54 +0200265 String sshkey = deviceKey.annotations().value(AnnotationKeys.SSHKEY);
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -0600266
267 deviceInfo = new NetconfDeviceInfo(username,
Andrea Campanellac3627842017-04-04 18:06:54 +0200268 password,
269 IpAddress.valueOf(ip),
270 port,
271 sshkey);
Himanshu Ranjan7c2ee3c2017-02-13 05:10:08 -0600272 } else {
273 log.error("Unknown device key for device {}", deviceId);
274 }
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700275 } catch (NullPointerException e) {
276 throw new NetconfException("No Device Key for device " + deviceId, e);
277 }
andreaeb70a942015-10-16 21:34:46 -0700278 }
Sean Condon54d82432017-07-26 22:27:25 +0100279 NetconfDevice netconfDevicedevice = createDevice(deviceInfo);
280 netconfDevicedevice.getSession().addDeviceOutputListener(downListener);
281 return netconfDevicedevice;
andreaeb70a942015-10-16 21:34:46 -0700282 }
283
284 @Override
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700285 public void disconnectDevice(DeviceId deviceId, boolean remove) {
286 if (!netconfDeviceMap.containsKey(deviceId)) {
287 log.warn("Device {} is not present", deviceId);
andreaeb70a942015-10-16 21:34:46 -0700288 } else {
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700289 stopDevice(deviceId, remove);
andreaeb70a942015-10-16 21:34:46 -0700290 }
291 }
292
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700293 private void stopDevice(DeviceId deviceId, boolean remove) {
294 netconfDeviceMap.get(deviceId).disconnect();
295 netconfDeviceMap.remove(deviceId);
296 if (remove) {
Andrea Campanella86294db2016-03-07 11:42:49 -0800297 for (NetconfDeviceListener l : netconfDeviceListeners) {
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700298 l.deviceRemoved(deviceId);
299 }
300 }
301 }
302
303 @Override
304 public void removeDevice(DeviceId deviceId) {
305 if (!netconfDeviceMap.containsKey(deviceId)) {
306 log.warn("Device {} is not present", deviceId);
307 for (NetconfDeviceListener l : netconfDeviceListeners) {
308 l.deviceRemoved(deviceId);
309 }
310 } else {
zhongguo zhao78eab372018-08-27 16:22:39 +0800311 stopDevice(deviceId, true);
Andrea Campanella86294db2016-03-07 11:42:49 -0800312 }
313 }
314
Andrea Campanella101417d2015-12-11 17:58:07 -0800315 private NetconfDevice createDevice(NetconfDeviceInfo deviceInfo) throws NetconfException {
Andrea Campanella950310c2016-02-12 18:14:38 -0800316 NetconfDevice netconfDevice = deviceFactory.createNetconfDevice(deviceInfo);
Andrea Campanella087ceb92015-12-07 09:58:34 -0800317 netconfDeviceMap.put(deviceInfo.getDeviceId(), netconfDevice);
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700318 for (NetconfDeviceListener l : netconfDeviceListeners) {
319 l.deviceAdded(deviceInfo.getDeviceId());
320 }
andreaeb70a942015-10-16 21:34:46 -0700321 return netconfDevice;
322 }
323
andreaeb70a942015-10-16 21:34:46 -0700324
325 @Override
326 public Map<DeviceId, NetconfDevice> getDevicesMap() {
327 return netconfDeviceMap;
328 }
Andrea Campanella950310c2016-02-12 18:14:38 -0800329
Andrea Campanella86294db2016-03-07 11:42:49 -0800330 @Override
331 public Set<DeviceId> getNetconfDevices() {
332 return netconfDeviceMap.keySet();
333 }
334
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700335
Yuta HIGUCHI2ee4fba2018-06-12 16:21:06 -0700336 /**
337 * Device factory for the specific NetconfDeviceImpl.
338 *
339 * @deprecated in 1.14.0
340 */
341 @Deprecated
Andrea Campanella950310c2016-02-12 18:14:38 -0800342 private class DefaultNetconfDeviceFactory implements NetconfDeviceFactory {
343
344 @Override
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700345 public NetconfDevice createNetconfDevice(NetconfDeviceInfo netconfDeviceInfo)
346 throws NetconfException {
Andrea Campanella950310c2016-02-12 18:14:38 -0800347 return new DefaultNetconfDevice(netconfDeviceInfo);
348 }
349 }
Andrea Campanella2464dc32016-02-17 17:54:53 -0800350
Yuta HIGUCHIf7089102017-05-03 10:31:46 -0700351 //Listener for closed session with devices, gets triggered when devices goes down
352 // or sends the end pattern ]]>]]>
Andrea Campanella2464dc32016-02-17 17:54:53 -0800353 private class DeviceDownEventListener implements NetconfDeviceOutputEventListener {
354
355 @Override
356 public void event(NetconfDeviceOutputEvent event) {
Andrea Campanellac3627842017-04-04 18:06:54 +0200357 DeviceId did = event.getDeviceInfo().getDeviceId();
Andrea Campanella2464dc32016-02-17 17:54:53 -0800358 if (event.type().equals(NetconfDeviceOutputEvent.Type.DEVICE_UNREGISTERED)) {
Andrea Campanellac3627842017-04-04 18:06:54 +0200359 removeDevice(did);
360 } else if (event.type().equals(NetconfDeviceOutputEvent.Type.SESSION_CLOSED)) {
361 log.info("Trying to reestablish connection with device {}", did);
362 executor.execute(() -> {
363 try {
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700364 NetconfDevice device = netconfDeviceMap.get(did);
365 if (device != null) {
366 device.getSession().checkAndReestablish();
367 log.info("Connection with device {} was reestablished", did);
368 } else {
369 log.warn("The device {} is not in the system", did);
370 }
371
Andrea Campanellac3627842017-04-04 18:06:54 +0200372 } catch (NetconfException e) {
373 log.error("The SSH connection with device {} couldn't be " +
Sean Condon54d82432017-07-26 22:27:25 +0100374 "reestablished due to {}. " +
375 "Marking the device as unreachable", e.getMessage());
Andrea Campanellac3627842017-04-04 18:06:54 +0200376 log.debug("Complete exception: ", e);
377 removeDevice(did);
378 }
379 });
Andrea Campanella2464dc32016-02-17 17:54:53 -0800380 }
381 }
382
383 @Override
384 public boolean isRelevant(NetconfDeviceOutputEvent event) {
385 return getDevicesMap().containsKey(event.getDeviceInfo().getDeviceId());
386 }
387 }
andreaeb70a942015-10-16 21:34:46 -0700388}