Started fleshing out the UI topo model classes.
If reviewing this, please refer to http://tinyurl.com/onos-ui-topo-model
Change-Id: I4738392bec1a89c37dff15eff6fe04d66fcabd95
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java
index 87afc56b..f7879ef 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java
@@ -16,8 +16,20 @@
package org.onosproject.ui.model.topo;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Encapsulates the notion of the ONOS cluster.
*/
-public class UiCluster extends UiElement {
+class UiCluster extends UiElement {
+
+ private final List<UiClusterMember> members = new ArrayList<>();
+
+ /**
+ * Removes all cluster members.
+ */
+ void clear() {
+ members.clear();
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiDevice.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiDevice.java
index f267ca5..78f9d47 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiDevice.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiDevice.java
@@ -16,8 +16,17 @@
package org.onosproject.ui.model.topo;
+import org.onosproject.net.Device;
+
/**
* Represents a device.
*/
public class UiDevice extends UiNode {
+
+ private Device device;
+
+ @Override
+ protected void destroy() {
+ device = null;
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiElement.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiElement.java
index 4f2f9cb..5e6144d 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiElement.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiElement.java
@@ -20,4 +20,12 @@
* Abstract base class of all elements in the UI topology model.
*/
public class UiElement {
+
+ /**
+ * Removes all external references, and prepares the instance for
+ * garbage collection. This default implementation does nothing.
+ */
+ protected void destroy() {
+ // does nothing
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiHost.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiHost.java
index cd80701..933e469 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiHost.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiHost.java
@@ -16,8 +16,17 @@
package org.onosproject.ui.model.topo;
+import org.onosproject.net.Host;
+
/**
* Represents an end-station host.
*/
public class UiHost extends UiNode {
+
+ private Host host;
+
+ @Override
+ protected void destroy() {
+ host = null;
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java
index fe1842e..f45a630 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java
@@ -16,8 +16,42 @@
package org.onosproject.ui.model.topo;
+import org.onosproject.net.Device;
+import org.onosproject.net.EdgeLink;
+import org.onosproject.net.Link;
+
+import java.util.Set;
+
/**
* Represents a bi-directional link backed by two uni-directional links.
*/
public class UiLink extends UiElement {
+
+ // devices at either end of this link
+ private Device deviceA;
+ private Device deviceB;
+
+ // two unidirectional links underlying this link...
+ private Link linkAtoB;
+ private Link linkBtoA;
+
+ // ==OR== : private (synthetic) host link
+ private EdgeLink edgeLink;
+
+ // ==OR== : set of underlying UI links that this link aggregates
+ private Set<UiLink> children;
+
+
+ @Override
+ protected void destroy() {
+ deviceA = null;
+ deviceB = null;
+ linkAtoB = null;
+ linkBtoA = null;
+ edgeLink = null;
+ if (children != null) {
+ children.clear();
+ children = null;
+ }
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java
index 53bdfde..e39a7d2 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java
@@ -19,5 +19,5 @@
/**
* Represents a node drawn on the topology view (region, device, host).
*/
-public abstract class UiNode extends UiElement {
+abstract class UiNode extends UiElement {
}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiRegion.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiRegion.java
index d933703..9a3d6fb 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiRegion.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiRegion.java
@@ -16,8 +16,34 @@
package org.onosproject.ui.model.topo;
+import org.onosproject.net.region.Region;
+
+import java.util.Set;
+import java.util.TreeSet;
+
/**
* Represents a region.
*/
public class UiRegion extends UiNode {
+
+ private final Set<UiDevice> uiDevices = new TreeSet<>();
+ private final Set<UiHost> uiHosts = new TreeSet<>();
+ private final Set<UiLink> uiLinks = new TreeSet<>();
+
+ private Region region;
+
+
+ @Override
+ protected void destroy() {
+ uiDevices.forEach(UiDevice::destroy);
+ uiHosts.forEach(UiHost::destroy);
+ uiLinks.forEach(UiLink::destroy);
+
+ uiDevices.clear();
+ uiHosts.clear();
+ uiLinks.clear();
+
+ region = null;
+ }
+
}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java
index 5f4195e..62293e0 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java
@@ -16,8 +16,29 @@
package org.onosproject.ui.model.topo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+import java.util.TreeSet;
+
/**
* Represents the overall network topology.
*/
public class UiTopology extends UiElement {
+
+ private static final Logger log = LoggerFactory.getLogger(UiTopology.class);
+
+ private final UiCluster uiCluster = new UiCluster();
+ private final Set<UiRegion> uiRegions = new TreeSet<>();
+
+ /**
+ * Clears the topology state; that is, drops all regions, devices, hosts,
+ * links, and cluster members.
+ */
+ public void clear() {
+ log.debug("clearing topology model");
+ uiRegions.clear();
+ uiCluster.clear();
+ }
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/ModelCache.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/ModelCache.java
index d72ff3d..6a76eb5 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/ModelCache.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/ModelCache.java
@@ -16,9 +16,19 @@
package org.onosproject.ui.impl.topo.model;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.RoleInfo;
import org.onosproject.event.EventDispatcher;
import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Link;
+import org.onosproject.net.region.Region;
import org.onosproject.ui.model.topo.UiDevice;
+import org.onosproject.ui.model.topo.UiTopology;
+
+import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_ADDED;
+import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_REMOVED;
/**
* UI Topology Model cache.
@@ -26,6 +36,7 @@
class ModelCache {
private final EventDispatcher dispatcher;
+ private final UiTopology uiTopology = new UiTopology();
ModelCache(EventDispatcher eventDispatcher) {
this.dispatcher = eventDispatcher;
@@ -35,7 +46,7 @@
* Clear our model.
*/
void clear() {
- // TODO: clear our internal state
+ uiTopology.clear();
}
/**
@@ -50,26 +61,72 @@
}
- // add or update device
void addOrUpdateDevice(Device device) {
- // fetch UiDevice
+ // TODO: find or create device assoc. with parameter
+ // FIXME
UiDevice uiDevice = new UiDevice();
- dispatcher.post(
- new UiModelEvent(UiModelEvent.Type.DEVICE_ADDED, uiDevice)
- );
-
+ // TODO: post the (correct) event
+ dispatcher.post(new UiModelEvent(DEVICE_ADDED, uiDevice));
}
void removeDevice(Device device) {
+ // TODO: get UiDevice associated with the given parameter; remove from model
+ // FIXME
UiDevice uiDevice = new UiDevice();
- dispatcher.post(
- new UiModelEvent(UiModelEvent.Type.DEVICE_REMOVED, uiDevice)
- );
+ // TODO: post the (correct) event
+ dispatcher.post(new UiModelEvent(DEVICE_REMOVED, uiDevice));
}
- // TODO remaining model objects
+ void addOrUpdateClusterMember(ControllerNode cnode) {
+ // TODO: find or create cluster member assoc. with parameter
+ // TODO: post event
+ }
+ void removeClusterMember(ControllerNode cnode) {
+ // TODO: find cluster member assoc. with parameter; remove from model
+ // TODO: post event
+ }
+
+
+ void updateMasterships(DeviceId deviceId, RoleInfo roleInfo) {
+ // TODO: store the updated mastership information
+ // TODO: post event
+ }
+
+ void addOrUpdateRegion(Region region) {
+ // TODO: find or create region assoc. with parameter
+ // TODO: post event
+ }
+
+ void removeRegion(Region region) {
+ // TODO: find region assoc. with parameter; remove from model
+ // TODO: post event
+ }
+
+ void addOrUpdateLink(Link link) {
+ // TODO: find ui-link assoc. with parameter; create or update.
+ // TODO: post event
+ }
+
+ void removeLink(Link link) {
+ // TODO: find ui-link assoc. with parameter; update or remove.
+ // TODO: post event
+ }
+
+ void addOrUpdateHost(Host host) {
+ // TODO: find or create host assoc. with parameter
+ // TODO: post event
+ }
+
+ void moveHost(Host host, Host prevHost) {
+ // TODO: process host-move
+ // TODO: post event
+ }
+
+ void removeHost(Host host) {
+ // TODO: find host assoc. with parameter; remove from model
+ }
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java
index 885eed2..0a4ce99 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java
@@ -25,6 +25,8 @@
import org.onosproject.cluster.ClusterEvent;
import org.onosproject.cluster.ClusterEventListener;
import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.RoleInfo;
import org.onosproject.event.AbstractListenerManager;
import org.onosproject.incubator.net.PortStatisticsService;
import org.onosproject.incubator.net.tunnel.TunnelService;
@@ -32,6 +34,9 @@
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Link;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
@@ -47,6 +52,7 @@
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkService;
+import org.onosproject.net.region.Region;
import org.onosproject.net.region.RegionEvent;
import org.onosproject.net.region.RegionListener;
import org.onosproject.net.region.RegionService;
@@ -178,28 +184,71 @@
private class InternalClusterListener implements ClusterEventListener {
@Override
public void event(ClusterEvent event) {
- // TODO: handle cluster event
+ ControllerNode cnode = event.subject();
+
+ switch (event.type()) {
+
+ case INSTANCE_ADDED:
+ case INSTANCE_ACTIVATED:
+ case INSTANCE_READY:
+ case INSTANCE_DEACTIVATED:
+ cache.addOrUpdateClusterMember(cnode);
+ break;
+
+ case INSTANCE_REMOVED:
+ cache.removeClusterMember(cnode);
+ break;
+
+ default:
+ break;
+ }
}
}
private class InternalMastershipListener implements MastershipListener {
@Override
public void event(MastershipEvent event) {
- // TODO: handle mastership event
+ DeviceId deviceId = event.subject();
+ RoleInfo roleInfo = event.roleInfo();
+
+ switch (event.type()) {
+ case MASTER_CHANGED:
+ case BACKUPS_CHANGED:
+ cache.updateMasterships(deviceId, roleInfo);
+ break;
+
+ default:
+ break;
+ }
}
}
private class InternalRegionListener implements RegionListener {
@Override
public void event(RegionEvent event) {
- // TODO: handle region event
+ Region region = event.subject();
+
+ switch (event.type()) {
+
+ case REGION_ADDED:
+ case REGION_UPDATED:
+ case REGION_MEMBERSHIP_CHANGED:
+ cache.addOrUpdateRegion(region);
+ break;
+
+ case REGION_REMOVED:
+ cache.removeRegion(region);
+ break;
+
+ default:
+ break;
+ }
}
}
private class InternalDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
-
Device device = event.subject();
switch (event.type()) {
@@ -224,28 +273,71 @@
private class InternalLinkListener implements LinkListener {
@Override
public void event(LinkEvent event) {
- // TODO: handle link event
+ Link link = event.subject();
+
+ switch (event.type()) {
+
+ case LINK_ADDED:
+ case LINK_UPDATED:
+ cache.addOrUpdateLink(link);
+ break;
+
+ case LINK_REMOVED:
+ cache.removeLink(link);
+ break;
+
+ default:
+ break;
+ }
}
}
private class InternalHostListener implements HostListener {
@Override
public void event(HostEvent event) {
- // TODO: handle host event
+ Host host = event.subject();
+ Host prevHost = event.prevSubject();
+
+ switch (event.type()) {
+
+ case HOST_ADDED:
+ case HOST_UPDATED:
+ cache.addOrUpdateHost(host);
+ break;
+
+ case HOST_MOVED:
+ cache.moveHost(host, prevHost);
+ break;
+
+ case HOST_REMOVED:
+ cache.removeHost(host);
+ break;
+
+ default:
+ break;
+ }
}
}
+ // =======================================================================
+ // NOTE: Neither intents nor flows are modeled by the UiTopology.
+ // Rather, they are serviced directly from this class.
+ // Additionally, since we are only retrieving counts (in the current
+ // implementation), we'll fetch them on demand from the service.
+ // Thus, the following internal listeners are stubs only (for now).
+ // =======================================================================
+
private class InternalIntentListener implements IntentListener {
@Override
public void event(IntentEvent event) {
- // TODO: handle intent event
+ // do nothing (for now)
}
}
private class InternalFlowRuleListener implements FlowRuleListener {
@Override
public void event(FlowRuleEvent event) {
- // TODO: handle flowrule event
+ // do nothing (for now)
}
}