[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/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java
index 210a237..eb41f4d 100644
--- a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java
+++ b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiDeviceDescriptionDiscovery.java
@@ -57,7 +57,7 @@
private static final Logger log = LoggerFactory
.getLogger(OpenConfigGnmiDeviceDescriptionDiscovery.class);
- private static final String LAST_CHANGE = "last-changed";
+ private static final String LAST_CHANGE = "last-change";
private static final String UNKNOWN = "unknown";
@@ -96,7 +96,6 @@
// Creates port descriptions with port name and port number
response.getNotificationList()
.forEach(notification -> {
- long timestamp = notification.getTimestamp();
notification.getUpdateList().forEach(update -> {
// /interfaces/interface[name=ifName]/state/...
final String ifName = update.getPath().getElem(1)
@@ -107,12 +106,17 @@
}
final DefaultPortDescription.Builder builder = ports.get(ifName);
final DefaultAnnotations.Builder annotationsBuilder = annotations.get(ifName);
- parseInterfaceInfo(update, ifName, builder, annotationsBuilder, timestamp);
+ parseInterfaceInfo(update, ifName, builder, annotationsBuilder);
});
});
final List<PortDescription> portDescriptionList = Lists.newArrayList();
ports.forEach((key, value) -> {
+ // For devices not providing last-change, we set it to 0
+ final DefaultAnnotations.Builder annotationsBuilder = annotations.get(key);
+ if (!annotationsBuilder.build().keys().contains(LAST_CHANGE)) {
+ annotationsBuilder.set(LAST_CHANGE, String.valueOf(0));
+ }
DefaultAnnotations annotation = annotations.get(key).build();
portDescriptionList.add(value.annotations(annotation).build());
});
@@ -140,9 +144,7 @@
private void parseInterfaceInfo(Update update,
String ifName,
DefaultPortDescription.Builder builder,
- DefaultAnnotations.Builder annotationsBuilder,
- long timestamp) {
-
+ DefaultAnnotations.Builder annotationsBuilder) {
final Path path = update.getPath();
final List<PathElem> elems = path.getElemList();
@@ -150,6 +152,7 @@
if (elems.size() == 4) {
// /interfaces/interface/state/ifindex
// /interfaces/interface/state/oper-status
+ // /interfaces/interface/state/last-change
final String pathElemName = elems.get(3).getName();
switch (pathElemName) {
case "ifindex": // port number
@@ -157,7 +160,9 @@
return;
case "oper-status":
builder.isEnabled(parseOperStatus(val.getStringVal()));
- annotationsBuilder.set(LAST_CHANGE, String.valueOf(timestamp));
+ return;
+ case "last-change":
+ annotationsBuilder.set(LAST_CHANGE, String.valueOf(val.getUintVal()));
return;
default:
break;
diff --git a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiPortStatisticsDiscovery.java b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiPortStatisticsDiscovery.java
index 6e361ff..bae396b 100644
--- a/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiPortStatisticsDiscovery.java
+++ b/drivers/gnmi/src/main/java/org/onosproject/drivers/gnmi/OpenConfigGnmiPortStatisticsDiscovery.java
@@ -22,11 +22,9 @@
import gnmi.Gnmi.GetRequest;
import gnmi.Gnmi.GetResponse;
import gnmi.Gnmi.Path;
-import org.apache.commons.lang3.tuple.Pair;
import org.onosproject.gnmi.api.GnmiClient;
import org.onosproject.gnmi.api.GnmiController;
import org.onosproject.grpc.utils.AbstractGrpcHandlerBehaviour;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DefaultPortStatistics;
@@ -48,9 +46,7 @@
extends AbstractGrpcHandlerBehaviour<GnmiClient, GnmiController>
implements PortStatisticsDiscovery {
- private static final Map<Pair<DeviceId, PortNumber>, Long> PORT_START_TIMES =
- Maps.newConcurrentMap();
- private static final String LAST_CHANGE = "last-changed";
+ private static final String LAST_CHANGE = "last-change";
public OpenConfigGnmiPortStatisticsDiscovery() {
super(GnmiController.class);
@@ -185,21 +181,16 @@
//FIXME log
return Duration.ZERO;
}
+
+ // Set duration 0 for devices that do not support reporting last-change
String lastChangedStr = port.annotations().value(LAST_CHANGE);
if (lastChangedStr == null) {
- //FIXME log
- // Falling back to the hack...
- // FIXME: This is a workaround since we cannot determine the port
- // duration from gNMI now
- final long now = System.currentTimeMillis() / 1000;
- final Long startTime = PORT_START_TIMES.putIfAbsent(
- Pair.of(deviceId, portNumber), now);
- return Duration.ofSeconds(startTime == null ? now : now - startTime);
+ return Duration.ZERO;
}
try {
long lastChanged = Long.parseLong(lastChangedStr);
- return timestamp.minus(lastChanged, ChronoUnit.NANOS);
+ return lastChanged == 0 ? Duration.ZERO : timestamp.minus(lastChanged, ChronoUnit.NANOS);
} catch (NullPointerException | NumberFormatException ex) {
//FIXME log
return Duration.ZERO;