Add uptimes to device and cluster REST APIs

Change-Id: I0ccdf4e33135be4bcfd1674a76ff4b39e992268b
This commit is contained in:
Ray Milkey 2018-03-22 13:37:11 -07:00
parent 348bba7ea0
commit 054e23d0cf
12 changed files with 78 additions and 12 deletions

View File

@ -20,13 +20,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Command;
import org.onlab.util.Tools;
import org.onosproject.cluster.ClusterAdminService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.core.Version;
import org.onosproject.utils.Comparators;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
@ -51,11 +49,7 @@ public class NodesListCommand extends AbstractShellCommand {
} else {
ControllerNode self = service.getLocalNode();
for (ControllerNode node : nodes) {
Instant lastUpdated = service.getLastUpdatedInstant(node.id());
String timeAgo = "Never";
if (lastUpdated != null) {
timeAgo = Tools.timeAgo(lastUpdated.toEpochMilli());
}
String timeAgo = service.localStatus(node.id());
Version version = service.getVersion(node.id());
print(FMT, node.id(), node.ip(), node.tcpPort(),
service.getState(node.id()),

View File

@ -20,6 +20,7 @@ import java.util.Optional;
import java.util.Set;
import org.joda.time.DateTime;
import org.onlab.util.Tools;
import org.onosproject.core.Version;
import org.onosproject.event.ListenerService;
@ -81,6 +82,21 @@ public interface ClusterService extends ListenerService<ClusterEvent, ClusterEve
.orElse(null);
}
/**
* Returns a human readable form of the system time when the availability state was last updated.
*
* @param nodeId controller node identifier
* @return human readable string for system time when the availability state was last updated.
*/
default String localStatus(NodeId nodeId) {
Instant lastUpdated = getLastUpdatedInstant(nodeId);
String timeAgo = "Never";
if (lastUpdated != null) {
timeAgo = Tools.timeAgo(lastUpdated.toEpochMilli());
}
return timeAgo;
}
/**
* Returns the system time when the availability state was last updated.
*

View File

@ -185,4 +185,14 @@ public interface DeviceService
*/
String localStatus(DeviceId deviceId);
/**
* Indicates how long ago the device connected or disconnected from this
* controller instance as a time offset.
*
* @param deviceId device identifier
* @return time offset in miliseconds
*/
long getLastUpdatedInstant(DeviceId deviceId);
}

View File

@ -142,4 +142,9 @@ public class DeviceServiceAdapter implements DeviceService {
return null;
}
@Override
public long getLastUpdatedInstant(DeviceId deviceId) {
return 0;
}
}

View File

@ -127,4 +127,9 @@ public abstract class ForwardingDeviceService implements DeviceService {
return delegate.localStatus(deviceId);
}
@Override
public long getLastUpdatedInstant(DeviceId deviceId) {
return delegate.getLastUpdatedInstant(deviceId);
}
}

View File

@ -40,7 +40,9 @@ public final class ControllerNodeCodec extends JsonCodec<ControllerNode> {
.put("id", node.id().toString())
.put("ip", node.ip().toString())
.put("tcpPort", node.tcpPort())
.put("status", service.getState(node.id()).toString());
.put("status", service.getState(node.id()).toString())
.put("lastUpdate", Long.toString(service.getLastUpdatedInstant(node.id()).toEpochMilli()))
.put("humanReadableLastUpdate", service.localStatus(node.id()));
}

View File

@ -47,7 +47,8 @@ public final class DeviceCodec extends AnnotatedCodec<Device> {
private static final String SERIAL = "serial";
private static final String CHASSIS_ID = "chassisId";
private static final String DRIVER = "driver";
private static final String LAST_UPDATE = "lastUpdate";
private static final String HUMAN_READABLE_LAST_UPDATE = "humanReadableLastUpdate";
@Override
public ObjectNode encode(Device device, CodecContext context) {
@ -64,7 +65,9 @@ public final class DeviceCodec extends AnnotatedCodec<Device> {
.put(SW, device.swVersion())
.put(SERIAL, device.serialNumber())
.put(DRIVER, driveService.getDriver(device.id()).name())
.put(CHASSIS_ID, device.chassisId().toString());
.put(CHASSIS_ID, device.chassisId().toString())
.put(LAST_UPDATE, Long.toString(service.getLastUpdatedInstant(device.id())))
.put(HUMAN_READABLE_LAST_UPDATE, service.localStatus(device.id()));
return annotate(result, device, context);
}

View File

@ -344,6 +344,15 @@ public class DeviceManager
return (ls.connected) ? "connected " + timeAgo : "disconnected " + timeAgo;
}
@Override
public long getLastUpdatedInstant(DeviceId deviceId) {
LocalStatus ls = deviceLocalStatus.get(deviceId);
if (ls == null) {
return 0;
}
return ls.dateTime.toEpochMilli();
}
// Check a device for control channel connectivity.
private boolean isReachable(DeviceId deviceId) {
if (deviceId == null) {

View File

@ -182,6 +182,12 @@ public class VirtualNetworkDeviceManager
return null;
}
@Override
public long getLastUpdatedInstant(DeviceId deviceId) {
// TODO not supported at this time
return 0;
}
/**
* Translates VirtualNetworkEvent to DeviceEvent.
*/

View File

@ -116,4 +116,9 @@ class NetconfDeviceServiceMock implements DeviceService {
public String localStatus(DeviceId deviceId) {
return null;
}
@Override
public long getLastUpdatedInstant(DeviceId deviceId) {
return 0;
}
}

View File

@ -151,4 +151,9 @@ public class MockDeviceService implements DeviceService {
// TODO Auto-generated method stub
return null;
}
@Override
public long getLastUpdatedInstant(DeviceId deviceId) {
return 0;
}
}

View File

@ -173,8 +173,8 @@ public class DevicesResourceTest extends ResourceTest {
@Override
public boolean matchesSafely(JsonArray json) {
final int minExpectedAttributes = 9;
final int maxExpectedAttributes = 10;
final int minExpectedAttributes = 11;
final int maxExpectedAttributes = 12;
boolean deviceFound = false;
@ -234,6 +234,12 @@ public class DevicesResourceTest extends ResourceTest {
expect(mockDeviceService.getRole(isA(DeviceId.class)))
.andReturn(MastershipRole.MASTER)
.anyTimes();
expect(mockDeviceService.getLastUpdatedInstant(isA(DeviceId.class)))
.andReturn(0L)
.anyTimes();
expect(mockDeviceService.localStatus(isA(DeviceId.class)))
.andReturn("")
.anyTimes();
// Register the services needed for the test