[SDFAB-199] Add the support for last-change
- Add parsing in OpenConfigGnmiDeviceDescriptionDiscovery and
defaults to 0 for the devices not providing last-change
- Remove hack in OpenConfigGnmiPortStatisticsDiscovery and set
the duration to 0 for the devices that do not support last-change
- Subscribe to the state changes of a given port and add parsing of
last-change timestamp in GnmiDeviceStateSubscribe
Note that if the device does not aggregate updates into a single notification
two PORT_UPDATED events will be generated. The first as consequence of the
operational status change and the second caused by the reconciliation which
updates correctly last-change
Change-Id: I6b2cb3652b306358bd9e701780946864a1ed324b
diff --git a/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GnmiDeviceStateSubscriber.java b/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GnmiDeviceStateSubscriber.java
index b7804bb..d55ca7f 100644
--- a/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GnmiDeviceStateSubscriber.java
+++ b/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GnmiDeviceStateSubscriber.java
@@ -62,7 +62,7 @@
@Beta
class GnmiDeviceStateSubscriber {
- private static final String LAST_CHANGE = "last-changed";
+ private static final String LAST_CHANGE = "last-change";
private static Logger log = LoggerFactory.getLogger(GnmiDeviceStateSubscriber.class);
@@ -126,13 +126,12 @@
&& !deviceService.getPorts(deviceId).isEmpty();
}
- private Path interfaceOperStatusPath(String interfaceName) {
+ private Path interfaceStatePath(String interfaceName) {
return Path.newBuilder()
.addElem(PathElem.newBuilder().setName("interfaces").build())
.addElem(PathElem.newBuilder()
.setName("interface").putKey("name", interfaceName).build())
.addElem(PathElem.newBuilder().setName("state").build())
- .addElem(PathElem.newBuilder().setName("oper-status").build())
.build();
}
@@ -163,7 +162,7 @@
.setUpdatesOnly(true)
.addAllSubscription(ports.stream().map(
port -> Subscription.newBuilder()
- .setPath(interfaceOperStatusPath(port.name()))
+ .setPath(interfaceStatePath(port.name()))
.setMode(SubscriptionMode.ON_CHANGE)
.build()).collect(Collectors.toList()))
.build();
@@ -183,19 +182,32 @@
return;
}
- List<Update> updateList = notification.getUpdateList();
- updateList.forEach(update -> {
- Path path = update.getPath();
- PathElem lastElem = path.getElem(path.getElemCount() - 1);
+ long lastChange = 0;
+ Update statusUpdate = null;
+ Path path;
+ PathElem lastElem;
+ // The assumption is that the notification contains all the updates:
+ // last-change, oper-status, counters, and so on. Otherwise, we need
+ // to put in place the aggregation logic in ONOS
+ for (Update update : notification.getUpdateList()) {
+ path = update.getPath();
+ lastElem = path.getElem(path.getElemCount() - 1);
// Use last element to identify which state updated
if ("oper-status".equals(lastElem.getName())) {
- handleOperStatusUpdate(eventSubject.deviceId(), update,
- notification.getTimestamp());
- } else {
+ statusUpdate = update;
+ } else if ("last-change".equals(lastElem.getName())) {
+ lastChange = update.getVal().getUintVal();
+ } else if (log.isDebugEnabled()) {
log.debug("Unrecognized update {}", GnmiUtils.pathToString(path));
}
- });
+ }
+
+ // Last-change could be not supported by the device
+ // Cannot proceed without the status update.
+ if (statusUpdate != null) {
+ handleOperStatusUpdate(eventSubject.deviceId(), statusUpdate, lastChange);
+ }
}
private void handleOperStatusUpdate(DeviceId deviceId, Update update, long timestamp) {