[ONOS-7149] Re-query DeviceDescription when Netconf device connects again
Change-Id: I4f22dc3e8a8a2eb0202925afb2ad7e4151ee6e46
diff --git a/drivers/netconf/src/main/java/org/onosproject/drivers/netconf/OvsNetconfDeviceDescriptionDiscovery.java b/drivers/netconf/src/main/java/org/onosproject/drivers/netconf/OvsNetconfDeviceDescriptionDiscovery.java
new file mode 100644
index 0000000..26a92ac
--- /dev/null
+++ b/drivers/netconf/src/main/java/org/onosproject/drivers/netconf/OvsNetconfDeviceDescriptionDiscovery.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.netconf;
+
+import com.google.common.collect.ImmutableList;
+import org.onlab.packet.ChassisId;
+import org.onosproject.net.Device;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Discovers the device detail of the ovs based simulator used in NETCONF SB testing and development.
+ */
+public class OvsNetconfDeviceDescriptionDiscovery
+ extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery {
+
+ private final Logger log = getLogger(getClass());
+
+ @Override
+ public DeviceDescription discoverDeviceDetails() {
+ log.debug("Discovering device details {}", handler().data().deviceId());
+ return new DefaultDeviceDescription(handler().data().deviceId().uri(),
+ Device.Type.VIRTUAL,
+ "Of-Config",
+ "VirtualBox",
+ "1.0",
+ "1",
+ new ChassisId());
+ }
+
+ @Override
+ public List<PortDescription> discoverPortDetails() {
+ log.debug("Discovering device ports {}", handler().data().deviceId());
+ return ImmutableList.of();
+ }
+}
diff --git a/drivers/netconf/src/main/resources/netconf-drivers.xml b/drivers/netconf/src/main/resources/netconf-drivers.xml
index 9ebe13f..8750507 100644
--- a/drivers/netconf/src/main/resources/netconf-drivers.xml
+++ b/drivers/netconf/src/main/resources/netconf-drivers.xml
@@ -16,19 +16,17 @@
-->
<drivers>
<!--This driver is for simulated NETCONF devices through of-config tool on top og OVSDB-->
- <driver name="ovs-netconf" manufacturer="" hwVersion="" swVersion="">
- <behaviour api="org.onosproject.net.behaviour.ControllerConfig"
- impl="org.onosproject.drivers.netconf.NetconfControllerConfig"/>
- <behaviour api="org.onosproject.net.behaviour.ConfigGetter"
- impl="org.onosproject.drivers.netconf.NetconfConfigGetter"/>
- <behaviour api="org.onosproject.net.behaviour.ConfigSetter"
- impl="org.onosproject.drivers.netconf.NetconfConfigSetter"/>
- </driver>
<driver name="netconf" manufacturer="" hwVersion="" swVersion="">
<behaviour api="org.onosproject.net.behaviour.ConfigGetter"
impl="org.onosproject.drivers.netconf.NetconfConfigGetter"/>
<behaviour api="org.onosproject.net.behaviour.ConfigSetter"
impl="org.onosproject.drivers.netconf.NetconfConfigSetter"/>
</driver>
+ <driver name="ovs-netconf" manufacturer="" hwVersion="" swVersion="" extends="netconf">
+ <behaviour api="org.onosproject.net.behaviour.ControllerConfig"
+ impl="org.onosproject.drivers.netconf.NetconfControllerConfig"/>
+ <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
+ impl="org.onosproject.drivers.netconf.OvsNetconfDeviceDescriptionDiscovery"/>
+ </driver>
</drivers>
diff --git a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
index a385b94..5b74680 100644
--- a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
+++ b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
@@ -388,63 +388,72 @@
log.debug("Connecting NETCONF device {}, on {}:{} with username {}",
deviceId, config.ip(), config.port(), config.username());
storeDeviceKey(config.sshKey(), config.username(), config.password(), deviceId);
- retriedPortDiscoveryMap.putIfAbsent(deviceId, new AtomicInteger(0));
+ retriedPortDiscoveryMap.put(deviceId, new AtomicInteger(0));
if (deviceService.getDevice(deviceId) == null) {
providerService.deviceConnected(deviceId, deviceDescription);
}
try {
- checkAndUpdateDevice(deviceId, deviceDescription);
+ checkAndUpdateDevice(deviceId, deviceDescription, true);
} catch (Exception e) {
log.error("Unhandled exception checking {}", deviceId, e);
}
}
- private void checkAndUpdateDevice(DeviceId deviceId, DeviceDescription deviceDescription) {
+ private void checkAndUpdateDevice(DeviceId deviceId, DeviceDescription deviceDescription, boolean newlyConnected) {
Device device = deviceService.getDevice(deviceId);
if (device == null) {
- log.debug("Device {} has not been added to store, " +
- "since it's not reachable", deviceId);
- } else {
- boolean isReachable = isReachable(deviceId);
- if (isReachable && !deviceService.isAvailable(deviceId)) {
- if (device.is(DeviceDescriptionDiscovery.class)) {
- if (mastershipService.isLocalMaster(deviceId)) {
- DeviceDescriptionDiscovery deviceDescriptionDiscovery =
- device.as(DeviceDescriptionDiscovery.class);
- DeviceDescription updatedDeviceDescription =
- deviceDescriptionDiscovery.discoverDeviceDetails();
- if (updatedDeviceDescription != null &&
- !descriptionEquals(device, updatedDeviceDescription)) {
- providerService.deviceConnected(
- deviceId, new DefaultDeviceDescription(
- updatedDeviceDescription, true,
- updatedDeviceDescription.annotations()));
- } else if (updatedDeviceDescription == null) {
- providerService.deviceConnected(
- deviceId, new DefaultDeviceDescription(
- deviceDescription, true,
- deviceDescription.annotations()));
- }
- }
- } else {
- log.warn("No DeviceDescriptionDiscovery behaviour for device {} " +
- "using DefaultDeviceDescription", deviceId);
+ log.debug("Device {} has not been added to store, since it's not reachable", deviceId);
+ return;
+ }
+ boolean isReachable = isReachable(deviceId);
+ if (!isReachable && deviceService.isAvailable(deviceId)) {
+ providerService.deviceDisconnected(deviceId);
+ return;
+ } else if (newlyConnected) {
+ retriedPortDiscoveryMap.putIfAbsent(deviceId, new AtomicInteger(0));
+ updateDeviceDescription(deviceId, deviceDescription, device);
+ }
+ if (isReachable && deviceService.isAvailable(deviceId) &&
+ mastershipService.isLocalMaster(deviceId)) {
+ //if ports are not discovered, retry the discovery
+ if (deviceService.getPorts(deviceId).isEmpty() &&
+ retriedPortDiscoveryMap.get(deviceId).getAndIncrement() < maxRetries) {
+ discoverPorts(deviceId);
+ }
+ updatePortStatistics(device);
+ }
+ }
+
+ private void updateDeviceDescription(DeviceId deviceId, DeviceDescription deviceDescription, Device device) {
+ if (device.is(DeviceDescriptionDiscovery.class)) {
+ if (mastershipService.isLocalMaster(deviceId)) {
+ DeviceDescriptionDiscovery deviceDescriptionDiscovery =
+ device.as(DeviceDescriptionDiscovery.class);
+ DeviceDescription updatedDeviceDescription =
+ deviceDescriptionDiscovery.discoverDeviceDetails();
+ if (updatedDeviceDescription == null && deviceDescription == null) {
+ log.debug("Both descriptions are null, skipping updates");
+ return;
+ }
+ if (updatedDeviceDescription == null) {
providerService.deviceConnected(
deviceId, new DefaultDeviceDescription(
- deviceDescription, true, deviceDescription.annotations()));
+ deviceDescription, true,
+ deviceDescription.annotations()));
+ } else if (deviceDescription == null ||
+ descriptionEquals(device, updatedDeviceDescription)) {
+ providerService.deviceConnected(
+ deviceId, new DefaultDeviceDescription(
+ updatedDeviceDescription, true,
+ updatedDeviceDescription.annotations()));
}
- } else if (!isReachable && deviceService.isAvailable(deviceId)) {
- providerService.deviceDisconnected(deviceId);
- } else if (isReachable && deviceService.isAvailable(deviceId) &&
- mastershipService.isLocalMaster(deviceId)) {
-
- //if ports are not discovered, retry the discovery
- if (deviceService.getPorts(deviceId).isEmpty() &&
- retriedPortDiscoveryMap.get(deviceId).getAndIncrement() < maxRetries) {
- discoverPorts(deviceId);
- }
- updatePortStatistics(device);
}
+ } else {
+ log.warn("No DeviceDescriptionDiscovery behaviour for device {} " +
+ "using DefaultDeviceDescription", deviceId);
+ providerService.deviceConnected(
+ deviceId, new DefaultDeviceDescription(
+ deviceDescription, true, deviceDescription.annotations()));
}
}
@@ -481,7 +490,7 @@
cfgService.getConfig(deviceId, NetconfDeviceConfig.class);
DeviceDescription deviceDescription = createDeviceRepresentation(deviceId, config);
storeDeviceKey(config.sshKey(), config.username(), config.password(), deviceId);
- checkAndUpdateDevice(deviceId, deviceDescription);
+ checkAndUpdateDevice(deviceId, deviceDescription, false);
});
}
@@ -637,8 +646,15 @@
private class InternalDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
+ DeviceId deviceId = event.subject().id();
if ((event.type() == DeviceEvent.Type.DEVICE_ADDED)) {
executor.execute(() -> discoverPorts(event.subject().id()));
+ } else if (event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED) {
+ if (deviceService.isAvailable(deviceId)) {
+ log.info("Availability changed to true, discovering ports and description");
+ checkAndUpdateDevice(deviceId, null, true);
+ //doDeviceUpdate(deviceId);
+ }
} else if ((event.type() == DeviceEvent.Type.DEVICE_REMOVED)) {
log.debug("removing device {}", event.subject().id());
controller.disconnectDevice(event.subject().id(), true);