GUI - Topologies - refactoring of ServicesBundle.
Jira: ONOS-6259
- also fixed bug where edge links were being omitted.
Change-Id: I19ac83d09ce7930de7a927fb2754e0c5004705f2
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/ProtectedIntentMonitor.java b/web/gui/src/main/java/org/onosproject/ui/impl/ProtectedIntentMonitor.java
index 28b761b..8ef929b 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/ProtectedIntentMonitor.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/ProtectedIntentMonitor.java
@@ -80,10 +80,12 @@
private static final Mod MOD_PROT_PRIMARY = new Mod(PROT_PRIMARY);
- private static final Set<Mod> PROTECTED_MOD_PRIMARY_SET = ImmutableSet.of(MOD_PROT_PRIMARY);
+ private static final Set<Mod> PROTECTED_MOD_PRIMARY_SET =
+ ImmutableSet.of(MOD_PROT_PRIMARY);
private static final Mod MOD_PROT_BACKUP = new Mod(PROT_BACKUP);
- private static final Set<Mod> PROTECTED_MOD_BACKUP_SET = ImmutableSet.of(MOD_PROT_BACKUP);
+ private static final Set<Mod> PROTECTED_MOD_BACKUP_SET =
+ ImmutableSet.of(MOD_PROT_BACKUP);
/**
@@ -95,7 +97,7 @@
}
private final long trafficPeriod;
- private final ServicesBundle servicesBundle;
+ private final ServicesBundle services;
private final TopologyViewMessageHandler msgHandler;
private final Timer timer = new Timer("topo-protected-intents");
@@ -108,16 +110,15 @@
/**
* Constructs a protected intent monitor.
*
- * @param trafficPeriod traffic task period in ms
- * @param servicesBundle bundle of services
- * @param msgHandler our message handler
+ * @param trafficPeriod traffic task period in ms
+ * @param services bundle of services
+ * @param msgHandler our message handler
*/
- public ProtectedIntentMonitor(long trafficPeriod, ServicesBundle servicesBundle,
+ public ProtectedIntentMonitor(long trafficPeriod, ServicesBundle services,
TopologyViewMessageHandler msgHandler) {
this.trafficPeriod = trafficPeriod;
- this.servicesBundle = servicesBundle;
+ this.services = services;
this.msgHandler = msgHandler;
-
}
// =======================================================================
@@ -200,7 +201,7 @@
private Highlights protectedIntentHighlights() {
Highlights highlights = new Highlights();
TrafficLinkMap linkMap = new TrafficLinkMap();
- IntentService intentService = servicesBundle.intentService();
+ IntentService intentService = services.intent();
if (selectedIntent != null) {
List<Intent> installables = intentService.getInstallableIntents(selectedIntent.key());
@@ -224,12 +225,12 @@
Set<Link> backup = new LinkedHashSet<>();
Map<Boolean, List<FlowRuleIntent>> transits = installables.stream()
- .filter(FlowRuleIntent.class::isInstance)
- .map(FlowRuleIntent.class::cast)
- // only consider fwd links so that ants march in one direction
- // TODO: didn't help need further investigation.
- //.filter(i -> !i.resources().contains(marker("rev")))
- .collect(Collectors.groupingBy(this::isPrimary));
+ .filter(FlowRuleIntent.class::isInstance)
+ .map(FlowRuleIntent.class::cast)
+ // only consider fwd links so that ants march in one direction
+ // TODO: didn't help need further investigation.
+ //.filter(i -> !i.resources().contains(marker("rev")))
+ .collect(Collectors.groupingBy(this::isPrimary));
// walk primary
ConnectPoint primHead = ep1.description().paths().get(0).output().connectPoint();
@@ -284,8 +285,8 @@
*/
private Set<Link> protectedIntentMultiLayer(ConnectPoint head, ConnectPoint tail) {
List<Link> links = new LinkedList<>();
- LinkService linkService = servicesBundle.linkService();
- IntentService intentService = servicesBundle.intentService();
+ LinkService linkService = services.link();
+ IntentService intentService = services.intent();
// Ingress cross connect link
links.addAll(
@@ -336,9 +337,9 @@
/**
* Populate Links along the primary/backup path.
*
- * @param links link collection to populate [output]
- * @param head head-end of primary/backup path
- * @param tail tail-end of primary/backup path
+ * @param links link collection to populate [output]
+ * @param head head-end of primary/backup path
+ * @param tail tail-end of primary/backup path
* @param transit Intents if any
*/
private void populateLinks(Set<Link> links,
@@ -359,11 +360,11 @@
.map(pn -> new ConnectPoint(fr.deviceId(), pn))
.orElse(null)
).filter(Objects::nonNull)
- .map(dst -> servicesBundle.linkService().getLink(head, dst))
+ .map(dst -> services.link().getLink(head, dst))
.filter(Objects::nonNull)
.findFirst()
// if there isn't one probably 1 hop to the tail
- .orElse(servicesBundle.linkService().getLink(head, tail));
+ .orElse(services.link().getLink(head, tail));
// add first link
if (first != null) {
@@ -387,7 +388,7 @@
.map(pn -> new ConnectPoint(fr.deviceId(), pn))
.orElse(null)
).filter(Objects::nonNull)
- .map(src -> servicesBundle.linkService().getLink(src, tail))
+ .map(src -> services.link().getLink(src, tail))
.filter(Objects::nonNull)
.findFirst()
.ifPresent(links::add);
@@ -406,7 +407,7 @@
// returns true if the backup path is the one where the traffic is currently flowing
private boolean usingBackup(Set<Link> primary) {
- Set<Link> activeLinks = Sets.newHashSet(servicesBundle.linkService().getActiveLinks());
+ Set<Link> activeLinks = Sets.newHashSet(services.link().getActiveLinks());
return primary.isEmpty() || !activeLinks.containsAll(primary);
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
index e20216d..1dbe3b1 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
@@ -29,7 +29,6 @@
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.event.Event;
-import org.onosproject.mastership.MastershipAdminService;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.net.ConnectPoint;
@@ -62,7 +61,7 @@
import org.onosproject.ui.JsonUtils;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
-import org.onosproject.ui.impl.TrafficMonitor.Mode;
+import org.onosproject.ui.impl.TrafficMonitorBase.Mode;
import org.onosproject.ui.topo.Highlights;
import org.onosproject.ui.topo.NodeSelection;
import org.onosproject.ui.topo.PropertyPanel;
@@ -83,9 +82,7 @@
import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.HostId.hostId;
-import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
-import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
-import static org.onosproject.net.device.DeviceEvent.Type.PORT_STATS_UPDATED;
+import static org.onosproject.net.device.DeviceEvent.Type.*;
import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
import static org.onosproject.ui.JsonUtils.envelope;
@@ -204,8 +201,8 @@
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
appId = directory.get(CoreService.class).registerApplication(MY_APP_ID);
- traffic = new TrafficMonitor(TRAFFIC_PERIOD, servicesBundle, this);
- protectedIntentMonitor = new ProtectedIntentMonitor(TRAFFIC_PERIOD, servicesBundle, this);
+ traffic = new TrafficMonitor(TRAFFIC_PERIOD, services, this);
+ protectedIntentMonitor = new ProtectedIntentMonitor(TRAFFIC_PERIOD, services, this);
}
@Override
@@ -398,7 +395,7 @@
@Override
public void process(ObjectNode payload) {
- directory.get(MastershipAdminService.class).balanceRoles();
+ services.mastershipAdmin().balanceRoles();
}
}
@@ -424,7 +421,7 @@
.two(two)
.build();
- intentService.submit(intent);
+ services.intent().submit(intent);
if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
traffic.monitor(intent);
}
@@ -446,17 +443,17 @@
long longKey = Long.decode(stringKey);
key = Key.of(longKey, applicId);
- intent = intentService.getIntent(key);
+ intent = services.intent().getIntent(key);
if (intent == null) {
// Intent might using string key, not long key
key = Key.of(stringKey, applicId);
- intent = intentService.getIntent(key);
+ intent = services.intent().getIntent(key);
}
} catch (NumberFormatException ex) {
// string key
key = Key.of(stringKey, applicId);
- intent = intentService.getIntent(key);
+ intent = services.intent().getIntent(key);
}
log.debug("Attempting to select intent by key={}", key);
@@ -481,9 +478,9 @@
} else {
log.debug("Withdrawing / Purging intent {}", intent.key());
if (isIntentToBePurged(payload)) {
- intentService.purge(intent);
+ services.intent().purge(intent);
} else {
- intentService.withdraw(intent);
+ services.intent().withdraw(intent);
}
}
}
@@ -501,7 +498,7 @@
log.warn("Unable to find intent from payload {}", payload);
} else {
log.debug("Resubmitting intent {}", intent.key());
- intentService.submit(intent);
+ services.intent().submit(intent);
}
}
}
@@ -516,7 +513,7 @@
// TODO: add protection against device ids and non-existent hosts.
Set<HostId> src = getHostIds((ArrayNode) payload.path(SRC));
HostId dst = hostId(string(payload, DST));
- Host dstHost = hostService.getHost(dst);
+ Host dstHost = services.host().getHost(dst);
Set<ConnectPoint> ingressPoints = getHostLocations(src);
@@ -534,7 +531,7 @@
.egressPoint(dstHost.location())
.build();
- intentService.submit(intent);
+ services.intent().submit(intent);
if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
traffic.monitor(intent);
}
@@ -586,6 +583,12 @@
}
}
+ private NodeSelection makeNodeSelection(ObjectNode payload) {
+ return new NodeSelection(payload, services.device(), services.host(),
+ services.link());
+ }
+
+
private final class ReqDevLinkFlows extends RequestHandler {
private ReqDevLinkFlows() {
super(REQ_DEV_LINK_FLOWS);
@@ -593,9 +596,7 @@
@Override
public void process(ObjectNode payload) {
- NodeSelection nodeSelection =
- new NodeSelection(payload, deviceService, hostService, linkService);
- traffic.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
+ traffic.monitor(Mode.DEV_LINK_FLOWS, makeNodeSelection(payload));
}
}
@@ -606,9 +607,7 @@
@Override
public void process(ObjectNode payload) {
- NodeSelection nodeSelection =
- new NodeSelection(payload, deviceService, hostService, linkService);
- traffic.monitor(Mode.RELATED_INTENTS, nodeSelection);
+ traffic.monitor(Mode.RELATED_INTENTS, makeNodeSelection(payload));
}
}
@@ -723,7 +722,7 @@
// Sends all controller nodes to the client as node-added messages.
private void sendAllInstances(String messageType) {
- List<ControllerNode> nodes = new ArrayList<>(clusterService.getNodes());
+ List<ControllerNode> nodes = new ArrayList<>(services.cluster().getNodes());
nodes.sort(NODE_COMPARATOR);
for (ControllerNode node : nodes) {
sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node),
@@ -734,13 +733,13 @@
// Sends all devices to the client as device-added messages.
private void sendAllDevices() {
// Send optical first, others later for layered rendering
- for (Device device : deviceService.getDevices()) {
+ for (Device device : services.device().getDevices()) {
if ((device.type() == Device.Type.ROADM) ||
(device.type() == Device.Type.OTN)) {
sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
}
}
- for (Device device : deviceService.getDevices()) {
+ for (Device device : services.device().getDevices()) {
if ((device.type() != Device.Type.ROADM) &&
(device.type() != Device.Type.OTN)) {
sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
@@ -751,12 +750,12 @@
// Sends all links to the client as link-added messages.
private void sendAllLinks() {
// Send optical first, others later for layered rendering
- for (Link link : linkService.getLinks()) {
+ for (Link link : services.link().getLinks()) {
if (link.type() == Link.Type.OPTICAL) {
sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
}
}
- for (Link link : linkService.getLinks()) {
+ for (Link link : services.link().getLinks()) {
if (link.type() != Link.Type.OPTICAL) {
sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
}
@@ -789,7 +788,7 @@
// Sends all hosts to the client as host-added messages.
private void sendAllHosts() {
- for (Host host : hostService.getHosts()) {
+ for (Host host : services.host().getHosts()) {
sendMessage(hostMessage(new HostEvent(HOST_ADDED, host)));
}
}
@@ -803,7 +802,7 @@
}
private HostLocation getHostLocation(HostId hostId) {
- return hostService.getHost(hostId).location();
+ return services.host().getHost(hostId).location();
}
// Produces a list of host ids from the specified JSON array.
@@ -838,26 +837,26 @@
// Adds all internal listeners.
private synchronized void addListeners() {
listenersRemoved = false;
- clusterService.addListener(clusterListener);
- mastershipService.addListener(mastershipListener);
- deviceService.addListener(deviceListener);
- linkService.addListener(linkListener);
- hostService.addListener(hostListener);
- intentService.addListener(intentListener);
- flowService.addListener(flowListener);
+ services.cluster().addListener(clusterListener);
+ services.mastership().addListener(mastershipListener);
+ services.device().addListener(deviceListener);
+ services.link().addListener(linkListener);
+ services.host().addListener(hostListener);
+ services.intent().addListener(intentListener);
+ services.flow().addListener(flowListener);
}
// Removes all internal listeners.
private synchronized void removeListeners() {
if (!listenersRemoved) {
listenersRemoved = true;
- clusterService.removeListener(clusterListener);
- mastershipService.removeListener(mastershipListener);
- deviceService.removeListener(deviceListener);
- linkService.removeListener(linkListener);
- hostService.removeListener(hostListener);
- intentService.removeListener(intentListener);
- flowService.removeListener(flowListener);
+ services.cluster().removeListener(clusterListener);
+ services.mastership().removeListener(mastershipListener);
+ services.device().removeListener(deviceListener);
+ services.link().removeListener(linkListener);
+ services.host().removeListener(hostListener);
+ services.intent().removeListener(intentListener);
+ services.flow().removeListener(flowListener);
}
}
@@ -879,7 +878,7 @@
public void event(MastershipEvent event) {
msgSender.execute(() -> {
sendAllInstances(UPDATE_INSTANCE);
- Device device = deviceService.getDevice(event.subject());
+ Device device = services.device().getDevice(event.subject());
if (device != null) {
sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device)));
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
index 7fb5d95..24b1773 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
@@ -22,15 +22,11 @@
import org.onlab.packet.IpAddress;
import org.onlab.util.DefaultHashMap;
import org.onosproject.cluster.ClusterEvent;
-import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.CoreService;
-import org.onosproject.incubator.net.PortStatisticsService;
import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
-import org.onosproject.incubator.net.tunnel.TunnelService;
-import org.onosproject.mastership.MastershipService;
import org.onosproject.net.Annotated;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
@@ -45,18 +41,11 @@
import org.onosproject.net.HostLocation;
import org.onosproject.net.Link;
import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.intent.IntentService;
import org.onosproject.net.link.LinkEvent;
-import org.onosproject.net.link.LinkService;
import org.onosproject.net.provider.ProviderId;
-import org.onosproject.net.statistic.StatisticService;
import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyService;
import org.onosproject.ui.JsonUtils;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
@@ -73,7 +62,6 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.ui.topo.TopoConstants.CoreButtons;
@@ -120,25 +108,6 @@
private static final ProviderId PID =
new ProviderId("core", "org.onosproject.core", true);
- protected static final String SHOW_HIGHLIGHTS = "showHighlights";
-
- protected ServiceDirectory directory;
- protected ClusterService clusterService;
- protected DeviceService deviceService;
- protected LinkService linkService;
- protected HostService hostService;
- protected MastershipService mastershipService;
- protected IntentService intentService;
- protected FlowRuleService flowService;
- protected StatisticService flowStatsService;
- protected PortStatisticsService portStatsService;
- protected TopologyService topologyService;
- protected TunnelService tunnelService;
-
- protected ServicesBundle servicesBundle;
-
- private String version;
-
// TODO: extract into an external & durable state; good enough for now and demo
private static Map<String, ObjectNode> metaUi = new ConcurrentHashMap<>();
@@ -151,27 +120,21 @@
return Collections.unmodifiableMap(metaUi);
}
+
+ protected ServicesBundle services;
+
+ private String version;
+
+
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
- this.directory = checkNotNull(directory, "Directory cannot be null");
- clusterService = directory.get(ClusterService.class);
- deviceService = directory.get(DeviceService.class);
- linkService = directory.get(LinkService.class);
- hostService = directory.get(HostService.class);
- mastershipService = directory.get(MastershipService.class);
- intentService = directory.get(IntentService.class);
- flowService = directory.get(FlowRuleService.class);
- flowStatsService = directory.get(StatisticService.class);
- portStatsService = directory.get(PortStatisticsService.class);
- topologyService = directory.get(TopologyService.class);
- tunnelService = directory.get(TunnelService.class);
+ services = new ServicesBundle(directory);
+ setVersionString(directory);
+ }
- servicesBundle = new ServicesBundle(intentService, deviceService,
- hostService, linkService,
- flowService,
- flowStatsService, portStatsService);
-
+ // Creates a palatable version string to display on the summary panel
+ private void setVersionString(ServiceDirectory directory) {
String ver = directory.get(CoreService.class).version().toString();
version = ver.replace(".SNAPSHOT", "*").replaceFirst("~.*$", "");
}
@@ -220,13 +183,13 @@
// Produces a cluster instance message to the client.
protected ObjectNode instanceMessage(ClusterEvent event, String msgType) {
ControllerNode node = event.subject();
- int switchCount = mastershipService.getDevicesOf(node.id()).size();
+ int switchCount = services.mastership().getDevicesOf(node.id()).size();
ObjectNode payload = objectNode()
.put("id", node.id().toString())
.put("ip", node.ip().toString())
- .put("online", clusterService.getState(node.id()).isActive())
- .put("ready", clusterService.getState(node.id()).isReady())
- .put("uiAttached", node.equals(clusterService.getLocalNode()))
+ .put("online", services.cluster().getState(node.id()).isActive())
+ .put("ready", services.cluster().getState(node.id()).isReady())
+ .put("uiAttached", node.equals(services.cluster().getLocalNode()))
.put("switches", switchCount);
ArrayNode labels = arrayNode();
@@ -251,7 +214,7 @@
ObjectNode payload = objectNode()
.put("id", device.id().toString())
.put("type", devType)
- .put("online", deviceService.isAvailable(device.id()))
+ .put("online", services.device().isAvailable(device.id()))
.put("master", master(device.id()));
// Generate labels: id, chassis id, no-label, optional-name
@@ -331,7 +294,7 @@
// Returns the name of the master node for the specified device id.
private String master(DeviceId deviceId) {
- NodeId master = mastershipService.getMasterFor(deviceId);
+ NodeId master = services.mastership().getMasterFor(deviceId);
return master != null ? master.toString() : "";
}
@@ -387,64 +350,62 @@
// Returns property panel model for summary response.
protected PropertyPanel summmaryMessage() {
- Topology topology = topologyService.currentTopology();
+ Topology topology = services.topology().currentTopology();
return new PropertyPanel("ONOS Summary", "node")
- .addProp(Properties.VERSION, version)
- .addSeparator()
- .addProp(Properties.DEVICES, deviceService.getDeviceCount())
- .addProp(Properties.LINKS, topology.linkCount())
- .addProp(Properties.HOSTS, hostService.getHostCount())
- .addProp(Properties.TOPOLOGY_SSCS, topology.clusterCount())
- .addSeparator()
- .addProp(Properties.INTENTS, intentService.getIntentCount())
- .addProp(Properties.TUNNELS, tunnelService.tunnelCount())
- .addProp(Properties.FLOWS, flowService.getFlowRuleCount());
+ .addProp(Properties.VERSION, version)
+ .addSeparator()
+ .addProp(Properties.DEVICES, services.device().getDeviceCount())
+ .addProp(Properties.LINKS, topology.linkCount())
+ .addProp(Properties.HOSTS, services.host().getHostCount())
+ .addProp(Properties.TOPOLOGY_SSCS, topology.clusterCount())
+ .addSeparator()
+ .addProp(Properties.INTENTS, services.intent().getIntentCount())
+ .addProp(Properties.TUNNELS, services.tunnel().tunnelCount())
+ .addProp(Properties.FLOWS, services.flow().getFlowRuleCount());
}
// Returns property panel model for device details response.
protected PropertyPanel deviceDetails(DeviceId deviceId) {
- Device device = deviceService.getDevice(deviceId);
+ Device device = services.device().getDevice(deviceId);
Annotations annot = device.annotations();
String name = annot.value(AnnotationKeys.NAME);
- int portCount = deviceService.getPorts(deviceId).size();
+ int portCount = services.device().getPorts(deviceId).size();
int flowCount = getFlowCount(deviceId);
int tunnelCount = getTunnelCount(deviceId);
String title = isNullOrEmpty(name) ? deviceId.toString() : name;
String typeId = device.type().toString().toLowerCase();
- PropertyPanel pp = new PropertyPanel(title, typeId)
- .id(deviceId.toString())
+ return new PropertyPanel(title, typeId)
+ .id(deviceId.toString())
- .addProp(Properties.URI, deviceId.toString())
- .addProp(Properties.VENDOR, device.manufacturer())
- .addProp(Properties.HW_VERSION, device.hwVersion())
- .addProp(Properties.SW_VERSION, device.swVersion())
- .addProp(Properties.SERIAL_NUMBER, device.serialNumber())
- .addProp(Properties.PROTOCOL, annot.value(AnnotationKeys.PROTOCOL))
- .addSeparator()
+ .addProp(Properties.URI, deviceId.toString())
+ .addProp(Properties.VENDOR, device.manufacturer())
+ .addProp(Properties.HW_VERSION, device.hwVersion())
+ .addProp(Properties.SW_VERSION, device.swVersion())
+ .addProp(Properties.SERIAL_NUMBER, device.serialNumber())
+ .addProp(Properties.PROTOCOL, annot.value(AnnotationKeys.PROTOCOL))
+ .addSeparator()
- .addProp(Properties.LATITUDE, annot.value(AnnotationKeys.LATITUDE))
- .addProp(Properties.LONGITUDE, annot.value(AnnotationKeys.LONGITUDE))
- .addSeparator()
+ .addProp(Properties.LATITUDE, annot.value(AnnotationKeys.LATITUDE))
+ .addProp(Properties.LONGITUDE, annot.value(AnnotationKeys.LONGITUDE))
+ .addSeparator()
- .addProp(Properties.PORTS, portCount)
- .addProp(Properties.FLOWS, flowCount)
- .addProp(Properties.TUNNELS, tunnelCount)
+ .addProp(Properties.PORTS, portCount)
+ .addProp(Properties.FLOWS, flowCount)
+ .addProp(Properties.TUNNELS, tunnelCount)
- .addButton(CoreButtons.SHOW_DEVICE_VIEW)
- .addButton(CoreButtons.SHOW_FLOW_VIEW)
- .addButton(CoreButtons.SHOW_PORT_VIEW)
- .addButton(CoreButtons.SHOW_GROUP_VIEW)
- .addButton(CoreButtons.SHOW_METER_VIEW);
-
- return pp;
+ .addButton(CoreButtons.SHOW_DEVICE_VIEW)
+ .addButton(CoreButtons.SHOW_FLOW_VIEW)
+ .addButton(CoreButtons.SHOW_PORT_VIEW)
+ .addButton(CoreButtons.SHOW_GROUP_VIEW)
+ .addButton(CoreButtons.SHOW_METER_VIEW);
}
protected int getFlowCount(DeviceId deviceId) {
int count = 0;
- for (FlowEntry flowEntry : flowService.getFlowEntries(deviceId)) {
+ for (FlowEntry flowEntry : services.flow().getFlowEntries(deviceId)) {
count++;
}
return count;
@@ -452,7 +413,7 @@
protected int getTunnelCount(DeviceId deviceId) {
int count = 0;
- Collection<Tunnel> tunnels = tunnelService.queryAllTunnels();
+ Collection<Tunnel> tunnels = services.tunnel().queryAllTunnels();
for (Tunnel tunnel : tunnels) {
//Only OpticalTunnelEndPoint has a device
if (!(tunnel.src() instanceof OpticalTunnelEndPoint) ||
@@ -476,7 +437,7 @@
// Returns host details response.
protected PropertyPanel hostDetails(HostId hostId) {
- Host host = hostService.getHost(hostId);
+ Host host = services.host().getHost(hostId);
Annotations annot = host.annotations();
String type = annot.value(AnnotationKeys.TYPE);
String name = annot.value(AnnotationKeys.NAME);
@@ -485,17 +446,14 @@
String title = isNullOrEmpty(name) ? hostId.toString() : name;
String typeId = isNullOrEmpty(type) ? "endstation" : type;
- PropertyPanel pp = new PropertyPanel(title, typeId)
- .id(hostId.toString())
- .addProp(Properties.MAC, host.mac())
- .addProp(Properties.IP, host.ipAddresses(), "[\\[\\]]")
- .addProp(Properties.VLAN, "-1".equals(vlan) ? "none" : vlan)
- .addSeparator()
- .addProp(Properties.LATITUDE, annot.value(AnnotationKeys.LATITUDE))
- .addProp(Properties.LONGITUDE, annot.value(AnnotationKeys.LONGITUDE));
-
- // Potentially add button descriptors here
- return pp;
+ return new PropertyPanel(title, typeId)
+ .id(hostId.toString())
+ .addProp(Properties.MAC, host.mac())
+ .addProp(Properties.IP, host.ipAddresses(), "[\\[\\]]")
+ .addProp(Properties.VLAN, "-1".equals(vlan) ? "none" : vlan)
+ .addSeparator()
+ .addProp(Properties.LATITUDE, annot.value(AnnotationKeys.LATITUDE))
+ .addProp(Properties.LONGITUDE, annot.value(AnnotationKeys.LONGITUDE));
}
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
index cc03524..660ba72 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
@@ -18,6 +18,7 @@
package org.onosproject.ui.impl;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import org.onosproject.incubator.net.PortStatisticsService.MetricType;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
@@ -47,7 +48,6 @@
import org.onosproject.ui.impl.topo.util.TrafficLink;
import org.onosproject.ui.impl.topo.util.TrafficLink.StatsType;
import org.onosproject.ui.impl.topo.util.TrafficLinkMap;
-import org.onosproject.ui.topo.AbstractTopoMonitor;
import org.onosproject.ui.topo.DeviceHighlight;
import org.onosproject.ui.topo.Highlights;
import org.onosproject.ui.topo.Highlights.Amount;
@@ -55,7 +55,6 @@
import org.onosproject.ui.topo.LinkHighlight.Flavor;
import org.onosproject.ui.topo.NodeHighlight;
import org.onosproject.ui.topo.NodeSelection;
-import org.onosproject.ui.topo.TopoUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,50 +66,25 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
import java.util.stream.Collectors;
import static org.onosproject.incubator.net.PortStatisticsService.MetricType.BYTES;
import static org.onosproject.incubator.net.PortStatisticsService.MetricType.PACKETS;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
-import static org.onosproject.ui.impl.TrafficMonitor.Mode.IDLE;
-import static org.onosproject.ui.impl.TrafficMonitor.Mode.RELATED_INTENTS;
-import static org.onosproject.ui.impl.TrafficMonitor.Mode.SELECTED_INTENT;
+import static org.onosproject.ui.impl.TrafficMonitorBase.Mode.RELATED_INTENTS;
+import static org.onosproject.ui.impl.TrafficMonitorBase.Mode.SELECTED_INTENT;
/**
* Encapsulates the behavior of monitoring specific traffic patterns.
*/
-public class TrafficMonitor extends AbstractTopoMonitor {
-
- // 4 Kilo Bytes as threshold
- private static final double BPS_THRESHOLD = 4 * TopoUtils.N_KILO;
+public class TrafficMonitor extends TrafficMonitorBase {
private static final Logger log =
LoggerFactory.getLogger(TrafficMonitor.class);
- /**
- * Designates the different modes of operation.
- */
- public enum Mode {
- IDLE,
- ALL_FLOW_TRAFFIC_BYTES,
- ALL_PORT_TRAFFIC_BIT_PS,
- ALL_PORT_TRAFFIC_PKT_PS,
- DEV_LINK_FLOWS,
- RELATED_INTENTS,
- SELECTED_INTENT
- }
-
- private final long trafficPeriod;
- private final ServicesBundle servicesBundle;
private final TopologyViewMessageHandler msgHandler;
private final TopoIntentFilter intentFilter;
- private final Timer timer = new Timer("topo-traffic");
-
- private TimerTask trafficTask = null;
- private Mode mode = IDLE;
private NodeSelection selectedNodes = null;
private IntentSelection selectedIntents = null;
@@ -124,8 +98,7 @@
*/
public TrafficMonitor(long trafficPeriod, ServicesBundle servicesBundle,
TopologyViewMessageHandler msgHandler) {
- this.trafficPeriod = trafficPeriod;
- this.servicesBundle = servicesBundle;
+ super(trafficPeriod, servicesBundle);
this.msgHandler = msgHandler;
intentFilter = new TopoIntentFilter(servicesBundle);
@@ -134,56 +107,7 @@
// =======================================================================
// === API ===
- /**
- * Monitor for traffic data to be sent back to the web client, under
- * the given mode. This causes a background traffic task to be
- * scheduled to repeatedly compute and transmit the appropriate traffic
- * data to the client.
- * <p>
- * The monitoring mode is expected to be one of:
- * <ul>
- * <li>ALL_FLOW_TRAFFIC_BYTES</li>
- * <li>ALL_PORT_TRAFFIC_BIT_PS</li>
- * <li>ALL_PORT_TRAFFIC_PKT_PS</li>
- * <li>SELECTED_INTENT</li>
- * </ul>
- *
- * @param mode monitoring mode
- */
- public synchronized void monitor(Mode mode) {
- log.debug("monitor: {}", mode);
- this.mode = mode;
-
- switch (mode) {
- case ALL_FLOW_TRAFFIC_BYTES:
- clearSelection();
- scheduleTask();
- sendAllFlowTraffic();
- break;
-
- case ALL_PORT_TRAFFIC_BIT_PS:
- clearSelection();
- scheduleTask();
- sendAllPortTraffic(StatsType.PORT_STATS);
- break;
-
- case ALL_PORT_TRAFFIC_PKT_PS:
- clearSelection();
- scheduleTask();
- sendAllPortTraffic(StatsType.PORT_PACKET_STATS);
- break;
-
- case SELECTED_INTENT:
- scheduleTask();
- sendSelectedIntentTraffic();
- break;
-
- default:
- log.debug("Unexpected call to monitor({})", mode);
- clearAll();
- break;
- }
- }
+ // monitor(Mode) is implemented in the super class
/**
* Monitor for traffic data to be sent back to the web client, under
@@ -211,7 +135,7 @@
case DEV_LINK_FLOWS:
// only care about devices (not hosts)
if (selectedNodes.devicesWithHover().isEmpty()) {
- sendClearAll();
+ clearAll();
} else {
scheduleTask();
sendDeviceLinkFlows();
@@ -220,11 +144,11 @@
case RELATED_INTENTS:
if (selectedNodes.none()) {
- sendClearAll();
+ clearAll();
} else {
selectedIntents = new IntentSelection(selectedNodes, intentFilter);
if (selectedIntents.none()) {
- sendClearAll();
+ clearAll();
} else {
sendSelectedIntents();
}
@@ -295,83 +219,57 @@
}
}
- /**
- * Stop all traffic monitoring.
- */
- public synchronized void stopMonitoring() {
- log.debug("STOP monitoring");
- if (mode != IDLE) {
- sendClearAll();
- }
- }
-
-
// =======================================================================
- // === Helper methods ===
+ // === Abstract method implementations ===
- private void sendClearAll() {
- clearAll();
- sendClearHighlights();
- }
-
- private void clearAll() {
- this.mode = IDLE;
- clearSelection();
- cancelTask();
- }
-
- private void clearSelection() {
- selectedNodes = null;
- selectedIntents = null;
- }
-
- private synchronized void scheduleTask() {
- if (trafficTask == null) {
- log.debug("Starting up background traffic task...");
- trafficTask = new TrafficUpdateTask();
- timer.schedule(trafficTask, trafficPeriod, trafficPeriod);
- } else {
- log.debug("(traffic task already running)");
- }
- }
-
- private synchronized void cancelTask() {
- if (trafficTask != null) {
- trafficTask.cancel();
- trafficTask = null;
- }
- }
-
- private void sendAllFlowTraffic() {
+ @Override
+ protected void sendAllFlowTraffic() {
log.debug("sendAllFlowTraffic");
msgHandler.sendHighlights(trafficSummary(StatsType.FLOW_STATS));
}
- private void sendAllPortTraffic(StatsType t) {
- log.debug("sendAllPortTraffic: {}", t);
- msgHandler.sendHighlights(trafficSummary(t));
+ @Override
+ protected void sendAllPortTrafficBits() {
+ log.debug("sendAllPortTrafficBits");
+ msgHandler.sendHighlights(trafficSummary(StatsType.PORT_STATS));
}
- private void sendDeviceLinkFlows() {
+ @Override
+ protected void sendAllPortTrafficPackets() {
+ log.debug("sendAllPortTrafficPackets");
+ msgHandler.sendHighlights(trafficSummary(StatsType.PORT_PACKET_STATS));
+ }
+
+ @Override
+ protected void sendDeviceLinkFlows() {
log.debug("sendDeviceLinkFlows: {}", selectedNodes);
msgHandler.sendHighlights(deviceLinkFlows());
}
- private void sendSelectedIntents() {
- log.debug("sendSelectedIntents: {}", selectedIntents);
- msgHandler.sendHighlights(intentGroup());
- }
-
- private void sendSelectedIntentTraffic() {
+ @Override
+ protected void sendSelectedIntentTraffic() {
log.debug("sendSelectedIntentTraffic: {}", selectedIntents);
msgHandler.sendHighlights(intentTraffic());
}
- private void sendClearHighlights() {
+ @Override
+ protected void sendClearHighlights() {
log.debug("sendClearHighlights");
msgHandler.sendHighlights(new Highlights());
}
+ @Override
+ protected void clearSelection() {
+ selectedNodes = null;
+ selectedIntents = null;
+ }
+
+
+ private void sendSelectedIntents() {
+ log.debug("sendSelectedIntents: {}", selectedIntents);
+ msgHandler.sendHighlights(intentGroup());
+ }
+
// =======================================================================
// === Generate messages in JSON object node format
@@ -450,7 +348,7 @@
allBut.remove(current);
secondary = allBut;
log.debug("Highlight intent: {} ([{}] of {})",
- current.id(), selectedIntents.index(), count);
+ current.id(), selectedIntents.index(), count);
}
highlightIntentLinks(highlights, primary, secondary);
@@ -466,7 +364,7 @@
Set<Intent> primary = new HashSet<>();
primary.add(current);
log.debug("Highlight traffic for intent: {} ([{}] of {})",
- current.id(), selectedIntents.index(), selectedIntents.size());
+ current.id(), selectedIntents.index(), selectedIntents.size());
highlightIntentLinksWithTraffic(highlights, primary);
highlights.subdueAllElse(Amount.MINIMALLY);
@@ -477,11 +375,11 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private void compileLinks(TrafficLinkMap linkMap) {
- servicesBundle.linkService().getLinks().forEach(linkMap::add);
+ services.link().getLinks().forEach(linkMap::add);
}
private void addEdgeLinks(TrafficLinkMap linkMap) {
- servicesBundle.hostService().getHosts().forEach(host -> {
+ services.host().getHosts().forEach(host -> {
linkMap.add(createEdgeLink(host, true));
linkMap.add(createEdgeLink(host, false));
});
@@ -489,7 +387,7 @@
private Load getLinkFlowLoad(Link link) {
if (link != null && link.src().elementId() instanceof DeviceId) {
- return servicesBundle.flowStatsService().load(link);
+ return services.flowStats().load(link);
}
return null;
}
@@ -504,8 +402,8 @@
// the max link rate of either direction
// (we choose 'one' since we know that is never null)
Link one = link.one();
- Load egressSrc = servicesBundle.portStatsService().load(one.src(), metricType);
- Load egressDst = servicesBundle.portStatsService().load(one.dst(), metricType);
+ Load egressSrc = services.portStats().load(one.src(), metricType);
+ Load egressDst = services.portStats().load(one.dst(), metricType);
link.addLoad(maxLoad(egressSrc, egressDst), metricType == BYTES ? BPS_THRESHOLD : 0);
}
@@ -523,14 +421,14 @@
private Map<Link, Integer> getLinkFlowCounts(DeviceId deviceId) {
// get the flows for the device
List<FlowEntry> entries = new ArrayList<>();
- for (FlowEntry flowEntry : servicesBundle.flowService().getFlowEntries(deviceId)) {
+ for (FlowEntry flowEntry : services.flow().getFlowEntries(deviceId)) {
entries.add(flowEntry);
}
// get egress links from device, and include edge links
- Set<Link> links = new HashSet<>(servicesBundle.linkService()
- .getDeviceEgressLinks(deviceId));
- Set<Host> hosts = servicesBundle.hostService().getConnectedHosts(deviceId);
+ Set<Link> links = new HashSet<>(services.link()
+ .getDeviceEgressLinks(deviceId));
+ Set<Host> hosts = services.host().getConnectedHosts(deviceId);
if (hosts != null) {
for (Host host : hosts) {
links.add(createEdgeLink(host, false));
@@ -582,7 +480,7 @@
TrafficLinkMap linkMap, Set<Intent> intents,
Flavor flavor, boolean showTraffic) {
for (Intent intent : intents) {
- List<Intent> installables = servicesBundle.intentService()
+ List<Intent> installables = services.intent()
.getInstallableIntents(intent.key());
Iterable<Link> links = null;
if (installables != null) {
@@ -596,8 +494,8 @@
// Add cross connect links
if (intent instanceof OpticalConnectivityIntent) {
OpticalConnectivityIntent ocIntent = (OpticalConnectivityIntent) intent;
- LinkService linkService = servicesBundle.linkService();
- DeviceService deviceService = servicesBundle.deviceService();
+ LinkService linkService = services.link();
+ DeviceService deviceService = services.device();
l.addAll(linkService.getDeviceIngressLinks(ocIntent.getSrc().deviceId()).stream()
.filter(i ->
deviceService.getDevice(i.src().deviceId()).type() == Device.Type.SWITCH)
@@ -609,13 +507,19 @@
}
links = l;
} else if (installable instanceof FlowObjectiveIntent) {
- links = addEdgeLinksIfNeeded(intent, linkResources(installable));
+ links = linkResources(installable);
} else if (installable instanceof LinkCollectionIntent) {
links = ((LinkCollectionIntent) installable).links();
} else if (installable instanceof OpticalPathIntent) {
links = ((OpticalPathIntent) installable).path().links();
}
+ if (links == null) {
+ links = Lists.newArrayList();
+ }
+
+ links = addEdgeLinksIfNeeded(intent, Lists.newArrayList(links));
+
boolean isOptical = intent instanceof OpticalConnectivityIntent;
processLinks(linkMap, links, flavor, isOptical, showTraffic);
updateHighlights(highlights, links);
@@ -629,8 +533,8 @@
if (parentIntent instanceof HostToHostIntent) {
links = new HashSet<>(links);
HostToHostIntent h2h = (HostToHostIntent) parentIntent;
- Host h1 = servicesBundle.hostService().getHost(h2h.one());
- Host h2 = servicesBundle.hostService().getHost(h2h.two());
+ Host h1 = services.host().getHost(h2h.one());
+ Host h2 = services.host().getHost(h2h.two());
links.add(createEdgeLink(h1, true));
links.add(createEdgeLink(h2, true));
}
@@ -688,42 +592,4 @@
}
}
- // =======================================================================
- // === Background Task
-
- // Provides periodic update of traffic information to the client
- private class TrafficUpdateTask extends TimerTask {
- @Override
- public void run() {
- try {
- switch (mode) {
- case ALL_FLOW_TRAFFIC_BYTES:
- sendAllFlowTraffic();
- break;
- case ALL_PORT_TRAFFIC_BIT_PS:
- sendAllPortTraffic(StatsType.PORT_STATS);
- break;
- case ALL_PORT_TRAFFIC_PKT_PS:
- sendAllPortTraffic(StatsType.PORT_PACKET_STATS);
- break;
- case DEV_LINK_FLOWS:
- sendDeviceLinkFlows();
- break;
- case SELECTED_INTENT:
- sendSelectedIntentTraffic();
- break;
-
- default:
- // RELATED_INTENTS and IDLE modes should never invoke
- // the background task, but if they do, they have
- // nothing to do
- break;
- }
-
- } catch (Exception e) {
- log.warn("Unable to process traffic task due to {}", e.getMessage());
- log.warn("Boom!", e);
- }
- }
- }
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitorBase.java b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitorBase.java
new file mode 100644
index 0000000..dfedaf3
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitorBase.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.ui.impl;
+
+import org.onosproject.ui.impl.topo.util.ServicesBundle;
+import org.onosproject.ui.topo.AbstractTopoMonitor;
+import org.onosproject.ui.topo.TopoUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import static org.onosproject.ui.impl.TrafficMonitorBase.Mode.IDLE;
+
+/**
+ * Base superclass for traffic monitor (both 'classic' and 'topo2' versions).
+ */
+public abstract class TrafficMonitorBase extends AbstractTopoMonitor {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ // 4 Kilo Bytes as threshold
+ static final double BPS_THRESHOLD = 4 * TopoUtils.N_KILO;
+
+
+ /**
+ * Designates the different modes of operation.
+ */
+ public enum Mode {
+ IDLE,
+ ALL_FLOW_TRAFFIC_BYTES,
+ ALL_PORT_TRAFFIC_BIT_PS,
+ ALL_PORT_TRAFFIC_PKT_PS,
+ DEV_LINK_FLOWS,
+ RELATED_INTENTS,
+ SELECTED_INTENT
+ }
+
+ /**
+ * Number of milliseconds between invocations of sending traffic data.
+ */
+ protected final long trafficPeriod;
+
+ /**
+ * Holds references to services.
+ */
+ protected final ServicesBundle services;
+
+ /**
+ * Current operating mode.
+ */
+ protected Mode mode = Mode.IDLE;
+
+ private final Timer timer;
+ private TimerTask trafficTask = null;
+
+ /**
+ * Constructs the monitor, initializing the task period and
+ * services bundle reference.
+ *
+ * @param trafficPeriod traffic task period in ms
+ * @param servicesBundle bundle of services
+ */
+ protected TrafficMonitorBase(long trafficPeriod,
+ ServicesBundle servicesBundle) {
+ this.trafficPeriod = trafficPeriod;
+ this.services = servicesBundle;
+ timer = new Timer("uiTopo-" + getClass().getSimpleName());
+ }
+
+ /**
+ * Initiates monitoring of traffic for a given mode.
+ * This causes a background traffic task to be
+ * scheduled to repeatedly compute and transmit the appropriate traffic
+ * data to the client.
+ * <p>
+ * The monitoring mode is expected to be one of:
+ * <ul>
+ * <li>ALL_FLOW_TRAFFIC_BYTES</li>
+ * <li>ALL_PORT_TRAFFIC_BIT_PS</li>
+ * <li>ALL_PORT_TRAFFIC_PKT_PS</li>
+ * <li>SELECTED_INTENT</li>
+ * </ul>
+ *
+ * @param mode the monitoring mode
+ */
+ public synchronized void monitor(Mode mode) {
+ this.mode = mode;
+
+ switch (mode) {
+
+ case ALL_FLOW_TRAFFIC_BYTES:
+ clearSelection();
+ scheduleTask();
+ sendAllFlowTraffic();
+ break;
+
+ case ALL_PORT_TRAFFIC_BIT_PS:
+ clearSelection();
+ scheduleTask();
+ sendAllPortTrafficBits();
+ break;
+
+ case ALL_PORT_TRAFFIC_PKT_PS:
+ clearSelection();
+ scheduleTask();
+ sendAllPortTrafficPackets();
+ break;
+
+ case SELECTED_INTENT:
+ sendSelectedIntentTraffic();
+ scheduleTask();
+ break;
+
+ default:
+ log.warn("Unexpected call to monitor({})", mode);
+ clearAll();
+ break;
+ }
+ }
+
+ /**
+ * Subclass should compile and send appropriate highlights data showing
+ * flow traffic (bytes on links).
+ */
+ protected abstract void sendAllFlowTraffic();
+
+ /**
+ * Subclass should compile and send appropriate highlights data showing
+ * bits per second, as computed using port stats.
+ */
+ protected abstract void sendAllPortTrafficBits();
+
+ /**
+ * Subclass should compile and send appropriate highlights data showing
+ * packets per second, as computed using port stats.
+ */
+ protected abstract void sendAllPortTrafficPackets();
+
+ /**
+ * Subclass should compile and send appropriate highlights data showing
+ * number of flows traversing links for the "selected" device(s).
+ */
+ protected abstract void sendDeviceLinkFlows();
+
+ /**
+ * Subclass should compile and send appropriate highlights data showing
+ * traffic traversing links for the "selected" intent.
+ */
+ protected abstract void sendSelectedIntentTraffic();
+
+ /**
+ * Subclass should send a "clear highlights" event.
+ */
+ protected abstract void sendClearHighlights();
+
+ /**
+ * Subclasses should clear any selection state.
+ */
+ protected abstract void clearSelection();
+
+ /**
+ * Sets the mode to IDLE, clears the selection, cancels the background
+ * task, and sends a clear highlights event to the client.
+ */
+ protected void clearAll() {
+ this.mode = Mode.IDLE;
+ clearSelection();
+ cancelTask();
+ sendClearHighlights();
+ }
+
+ /**
+ * Schedules the background monitor task to run.
+ */
+ protected synchronized void scheduleTask() {
+ if (trafficTask == null) {
+ log.debug("Starting up background traffic task...");
+ trafficTask = new TrafficUpdateTask();
+ timer.schedule(trafficTask, trafficPeriod, trafficPeriod);
+ } else {
+ log.debug("(traffic task already running)");
+ }
+ }
+
+ /**
+ * Cancels the background monitor task.
+ */
+ protected synchronized void cancelTask() {
+ if (trafficTask != null) {
+ trafficTask.cancel();
+ trafficTask = null;
+ }
+ }
+
+ /**
+ * Stops monitoring. (Invokes {@link #clearAll}, if not idle).
+ */
+ public synchronized void stopMonitoring() {
+ log.debug("STOP monitoring");
+ if (mode != IDLE) {
+ clearAll();
+ }
+ }
+
+
+ // =======================================================================
+ // === Background Task
+
+ // Provides periodic update of traffic information to the client
+ private class TrafficUpdateTask extends TimerTask {
+ @Override
+ public void run() {
+ try {
+ switch (mode) {
+ case ALL_FLOW_TRAFFIC_BYTES:
+ sendAllFlowTraffic();
+ break;
+ case ALL_PORT_TRAFFIC_BIT_PS:
+ sendAllPortTrafficBits();
+ break;
+ case ALL_PORT_TRAFFIC_PKT_PS:
+ sendAllPortTrafficPackets();
+ break;
+ case DEV_LINK_FLOWS:
+ sendDeviceLinkFlows();
+ break;
+ case SELECTED_INTENT:
+ sendSelectedIntentTraffic();
+ break;
+
+ default:
+ // RELATED_INTENTS and IDLE modes should never invoke
+ // the background task, but if they do, they have
+ // nothing to do
+ break;
+ }
+
+ } catch (Exception e) {
+ log.warn("Unable to process traffic task due to {}", e.getMessage());
+ log.warn("Boom!", e);
+ }
+ }
+ }
+
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2TrafficMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2TrafficMessageHandler.java
index 8a6ec8b..6b72e89 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2TrafficMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/Topo2TrafficMessageHandler.java
@@ -23,6 +23,7 @@
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.impl.topo.util.ServicesBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,13 +43,25 @@
// === Outbound event identifiers
private static final String HIGHLIGHTS = "topo2Highlights";
+
+ private static final long TRAFFIC_PERIOD = 5000;
+
// private UiTopoSession topoSession;
// private Topo2Jsonifier t2json;
+ protected ServicesBundle services;
+ private String version;
+
+
+ private Traffic2Monitor traffic;
+
+
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
+ services = new ServicesBundle(directory);
+
// get the topo session from the UiWebSocket
// topoSession = ((UiWebSocket) connection).topoSession();
// t2json = new Topo2Jsonifier(directory, connection.userName());
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/Traffic2Monitor.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/Traffic2Monitor.java
new file mode 100644
index 0000000..7aedc48
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/Traffic2Monitor.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.ui.impl.topo;
+
+import org.onosproject.ui.impl.TrafficMonitorBase;
+import org.onosproject.ui.impl.topo.util.ServicesBundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encapsulates the behavior of monitoring specific traffic patterns in the
+ * Topology-2 view.
+ */
+public class Traffic2Monitor extends TrafficMonitorBase {
+
+ private static final Logger log =
+ LoggerFactory.getLogger(Traffic2Monitor.class);
+
+ /**
+ * Constructs a traffic monitor.
+ *
+ * @param trafficPeriod traffic task period in ms
+ * @param servicesBundle bundle of services
+ */
+ public Traffic2Monitor(long trafficPeriod, ServicesBundle servicesBundle) {
+ super(trafficPeriod, servicesBundle);
+ }
+
+ @Override
+ protected void sendAllFlowTraffic() {
+ // TODO
+ }
+
+ @Override
+ protected void sendAllPortTrafficBits() {
+ // TODO
+ }
+
+ @Override
+ protected void sendAllPortTrafficPackets() {
+ // TODO
+ }
+
+ @Override
+ protected void sendDeviceLinkFlows() {
+ // NOTE: currently this monitor holds no state - nothing to do
+ }
+
+ @Override
+ protected void sendSelectedIntentTraffic() {
+ // NOTE: currently this monitor holds no state - nothing to do
+ }
+
+ @Override
+ protected void sendClearHighlights() {
+ // TODO
+ }
+
+ @Override
+ protected void clearSelection() {
+ // NOTE: currently this monitor holds no state - nothing to do
+ }
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/ServicesBundle.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/ServicesBundle.java
index 13bf1c2..aa20990 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/ServicesBundle.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/ServicesBundle.java
@@ -16,63 +16,83 @@
package org.onosproject.ui.impl.topo.util;
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.cluster.ClusterService;
import org.onosproject.incubator.net.PortStatisticsService;
+import org.onosproject.incubator.net.tunnel.TunnelService;
+import org.onosproject.mastership.MastershipAdminService;
+import org.onosproject.mastership.MastershipService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.statistic.StatisticService;
+import org.onosproject.net.topology.TopologyService;
import static com.google.common.base.Preconditions.checkNotNull;
/**
- * A bundle of services that the topology view requires to get its job done.
+ * A bundle of services that the topology view(s) require to get the job done.
*/
public class ServicesBundle {
- private final IntentService intentService;
- private final DeviceService deviceService;
- private final HostService hostService;
- private final LinkService linkService;
- private final FlowRuleService flowService;
- private final StatisticService flowStatsService;
- private final PortStatisticsService portStatsService;
+ private ClusterService clusterService;
+
+ private TopologyService topologyService;
+ private DeviceService deviceService;
+ private HostService hostService;
+ private LinkService linkService;
+ private TunnelService tunnelService;
+
+ private MastershipService mastershipService;
+ private MastershipAdminService mastershipAdminService;
+ private IntentService intentService;
+ private FlowRuleService flowService;
+ private StatisticService flowStatsService;
+ private PortStatisticsService portStatsService;
+
/**
- * Creates the services bundle.
+ * Creates the services bundle, from the given directly.
*
- * @param intentService intent service reference
- * @param deviceService device service reference
- * @param hostService host service reference
- * @param linkService link service reference
- * @param flowService flow service reference
- * @param flowStatsService flow statistics service reference
- * @param portStatsService port statistics service reference
+ * @param directory service directory
*/
- public ServicesBundle(IntentService intentService,
- DeviceService deviceService,
- HostService hostService,
- LinkService linkService,
- FlowRuleService flowService,
- StatisticService flowStatsService,
- PortStatisticsService portStatsService) {
- this.intentService = checkNotNull(intentService);
- this.deviceService = checkNotNull(deviceService);
- this.hostService = checkNotNull(hostService);
- this.linkService = checkNotNull(linkService);
- this.flowService = checkNotNull(flowService);
- this.flowStatsService = checkNotNull(flowStatsService);
- this.portStatsService = checkNotNull(portStatsService);
+ public ServicesBundle(ServiceDirectory directory) {
+ checkNotNull(directory, "Directory cannot be null");
+
+ clusterService = directory.get(ClusterService.class);
+
+ topologyService = directory.get(TopologyService.class);
+ deviceService = directory.get(DeviceService.class);
+ hostService = directory.get(HostService.class);
+ linkService = directory.get(LinkService.class);
+ tunnelService = directory.get(TunnelService.class);
+
+ mastershipService = directory.get(MastershipService.class);
+ mastershipAdminService = directory.get(MastershipAdminService.class);
+ intentService = directory.get(IntentService.class);
+ flowService = directory.get(FlowRuleService.class);
+ flowStatsService = directory.get(StatisticService.class);
+ portStatsService = directory.get(PortStatisticsService.class);
}
/**
- * Returns a reference to the intent service.
+ * Returns a reference to the cluster service.
*
- * @return intent service reference
+ * @return cluster service reference
*/
- public IntentService intentService() {
- return intentService;
+ public ClusterService cluster() {
+ return clusterService;
+ }
+
+ /**
+ * Returns a reference to the topology service.
+ *
+ * @return topology service reference
+ */
+ public TopologyService topology() {
+ return topologyService;
}
/**
@@ -80,7 +100,7 @@
*
* @return device service reference
*/
- public DeviceService deviceService() {
+ public DeviceService device() {
return deviceService;
}
@@ -89,7 +109,7 @@
*
* @return host service reference
*/
- public HostService hostService() {
+ public HostService host() {
return hostService;
}
@@ -98,16 +118,52 @@
*
* @return link service reference
*/
- public LinkService linkService() {
+ public LinkService link() {
return linkService;
}
/**
+ * Returns a reference to the tunnel service.
+ *
+ * @return tunnel service reference
+ */
+ public TunnelService tunnel() {
+ return tunnelService;
+ }
+
+ /**
+ * Returns a reference to the mastership service.
+ *
+ * @return mastership service reference
+ */
+ public MastershipService mastership() {
+ return mastershipService;
+ }
+
+ /**
+ * Returns a reference to the mastership admin service.
+ *
+ * @return mastership admin service reference
+ */
+ public MastershipAdminService mastershipAdmin() {
+ return mastershipAdminService;
+ }
+
+ /**
+ * Returns a reference to the intent service.
+ *
+ * @return intent service reference
+ */
+ public IntentService intent() {
+ return intentService;
+ }
+
+ /**
* Returns a reference to the flow rule service.
*
* @return flow service reference
*/
- public FlowRuleService flowService() {
+ public FlowRuleService flow() {
return flowService;
}
@@ -116,7 +172,7 @@
*
* @return flow statistics service reference
*/
- public StatisticService flowStatsService() {
+ public StatisticService flowStats() {
return flowStatsService;
}
@@ -125,7 +181,7 @@
*
* @return port statistics service reference
*/
- public PortStatisticsService portStatsService() {
+ public PortStatisticsService portStats() {
return portStatsService;
}
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TopoIntentFilter.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TopoIntentFilter.java
index e43fbf2..1dbe8f3 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TopoIntentFilter.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TopoIntentFilter.java
@@ -21,9 +21,7 @@
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.Link;
-import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.host.HostService;
import org.onosproject.net.intent.FlowObjectiveIntent;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.HostToHostIntent;
@@ -52,8 +50,6 @@
public class TopoIntentFilter {
private final IntentService intentService;
- private final DeviceService deviceService;
- private final HostService hostService;
private final LinkService linkService;
/**
@@ -62,19 +58,17 @@
* @param services service references bundle
*/
public TopoIntentFilter(ServicesBundle services) {
- this.intentService = services.intentService();
- this.deviceService = services.deviceService();
- this.hostService = services.hostService();
- this.linkService = services.linkService();
+ this.intentService = services.intent();
+ this.linkService = services.link();
}
/**
* Finds all path (host-to-host or point-to-point) intents that pertain
* to the given hosts and devices.
*
- * @param hosts set of hosts to query by
- * @param devices set of devices to query by
- * @param links set of links to query by
+ * @param hosts set of hosts to query by
+ * @param devices set of devices to query by
+ * @param links set of links to query by
* @return set of intents that 'match' all hosts, devices and links given
*/
public List<Intent> findPathIntents(Set<Host> hosts,