Committed by
Gerrit Code Review
TopoRegions: created skeleton Topo2 UI view for development of the "region-aware" topology.
- Added initial event generation (layout/region/ etc.) -- WIP Change-Id: I2f93eea7505ff0400085d7f67491f6b61231cb86
Showing
22 changed files
with
1119 additions
and
20 deletions
... | @@ -89,6 +89,17 @@ public abstract class RequestHandler { | ... | @@ -89,6 +89,17 @@ public abstract class RequestHandler { |
89 | 89 | ||
90 | /** | 90 | /** |
91 | * Sends a message back to the client. | 91 | * Sends a message back to the client. |
92 | + * | ||
93 | + * @param eventType message event type | ||
94 | + * @param payload message payload | ||
95 | + */ | ||
96 | + protected void sendMessage(String eventType, ObjectNode payload) { | ||
97 | + // TODO: remove sid | ||
98 | + parent.connection().sendMessage(eventType, 0, payload); | ||
99 | + } | ||
100 | + | ||
101 | + /** | ||
102 | + * Sends a message back to the client. | ||
92 | * Here, the message is preformatted; the assumption is it has its | 103 | * Here, the message is preformatted; the assumption is it has its |
93 | * eventType, sid and payload attributes already filled in. | 104 | * eventType, sid and payload attributes already filled in. |
94 | * | 105 | * | ... | ... |
... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
17 | package org.onosproject.ui.model.topo; | 17 | package org.onosproject.ui.model.topo; |
18 | 18 | ||
19 | import com.google.common.base.MoreObjects; | 19 | import com.google.common.base.MoreObjects; |
20 | +import org.onosproject.cluster.NodeId; | ||
20 | import org.onosproject.net.Device; | 21 | import org.onosproject.net.Device; |
21 | import org.onosproject.net.DeviceId; | 22 | import org.onosproject.net.DeviceId; |
22 | import org.onosproject.net.region.RegionId; | 23 | import org.onosproject.net.region.RegionId; |
... | @@ -30,6 +31,8 @@ public class UiDevice extends UiNode { | ... | @@ -30,6 +31,8 @@ public class UiDevice extends UiNode { |
30 | private final Device device; | 31 | private final Device device; |
31 | 32 | ||
32 | private RegionId regionId; | 33 | private RegionId regionId; |
34 | + private NodeId masterId; | ||
35 | + private boolean online; | ||
33 | 36 | ||
34 | /** | 37 | /** |
35 | * Creates a new UI device. | 38 | * Creates a new UI device. |
... | @@ -51,6 +54,24 @@ public class UiDevice extends UiNode { | ... | @@ -51,6 +54,24 @@ public class UiDevice extends UiNode { |
51 | this.regionId = regionId; | 54 | this.regionId = regionId; |
52 | } | 55 | } |
53 | 56 | ||
57 | + /** | ||
58 | + * Sets the ID of the controller node that holds mastership for this device. | ||
59 | + * | ||
60 | + * @param masterId master identifier | ||
61 | + */ | ||
62 | + public void setMasterId(NodeId masterId) { | ||
63 | + this.masterId = masterId; | ||
64 | + } | ||
65 | + | ||
66 | + /** | ||
67 | + * Sets a flag indicating whether the backing device is online. | ||
68 | + * | ||
69 | + * @param online boolen flag | ||
70 | + */ | ||
71 | + public void setOnline(boolean online) { | ||
72 | + this.online = online; | ||
73 | + } | ||
74 | + | ||
54 | @Override | 75 | @Override |
55 | public String toString() { | 76 | public String toString() { |
56 | return MoreObjects.toStringHelper(this) | 77 | return MoreObjects.toStringHelper(this) |
... | @@ -104,4 +125,32 @@ public class UiDevice extends UiNode { | ... | @@ -104,4 +125,32 @@ public class UiDevice extends UiNode { |
104 | public UiRegion uiRegion() { | 125 | public UiRegion uiRegion() { |
105 | return topology.findRegion(regionId); | 126 | return topology.findRegion(regionId); |
106 | } | 127 | } |
128 | + | ||
129 | + /** | ||
130 | + * Returns a string representation of the type of the backing device. | ||
131 | + * | ||
132 | + * @return the device type | ||
133 | + */ | ||
134 | + public String type() { | ||
135 | + return device.type().toString().toLowerCase(); | ||
136 | + } | ||
137 | + | ||
138 | + /** | ||
139 | + * Returns a boolean indicating whether the backing device is online. | ||
140 | + * | ||
141 | + * @return true if device is online, false otherwise | ||
142 | + */ | ||
143 | + public boolean isOnline() { | ||
144 | + return online; | ||
145 | + } | ||
146 | + | ||
147 | + /** | ||
148 | + * Returns the identifier for the cluster member that has | ||
149 | + * mastership over this device. | ||
150 | + * | ||
151 | + * @return master cluster member identifier | ||
152 | + */ | ||
153 | + public NodeId master() { | ||
154 | + return masterId; | ||
155 | + } | ||
107 | } | 156 | } | ... | ... |
... | @@ -20,4 +20,41 @@ package org.onosproject.ui.model.topo; | ... | @@ -20,4 +20,41 @@ package org.onosproject.ui.model.topo; |
20 | * Represents a node drawn on the topology view (region, device, host). | 20 | * Represents a node drawn on the topology view (region, device, host). |
21 | */ | 21 | */ |
22 | abstract class UiNode extends UiElement { | 22 | abstract class UiNode extends UiElement { |
23 | + | ||
24 | + /** | ||
25 | + * Default "layer" tag. | ||
26 | + */ | ||
27 | + public static final String LAYER_DEFAULT = "def"; | ||
28 | + | ||
29 | + /** | ||
30 | + * Packet layer tag. | ||
31 | + */ | ||
32 | + public static final String LAYER_PACKET = "pkt"; | ||
33 | + | ||
34 | + /** | ||
35 | + * Optical layer tag. | ||
36 | + */ | ||
37 | + public static final String LAYER_OPTICAL = "opt"; | ||
38 | + | ||
39 | + | ||
40 | + private String layer = LAYER_DEFAULT; | ||
41 | + | ||
42 | + /** | ||
43 | + * Returns the tag for the "layer" that the node should be rendered in | ||
44 | + * when viewed in the oblique view. | ||
45 | + * | ||
46 | + * @return the node's layer | ||
47 | + */ | ||
48 | + public String layer() { | ||
49 | + return layer; | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * Sets this node's "layer", for layered rendering. | ||
54 | + * | ||
55 | + * @param layerTag the layer tag to set | ||
56 | + */ | ||
57 | + public void setLayer(String layerTag) { | ||
58 | + layer = layerTag; | ||
59 | + } | ||
23 | } | 60 | } | ... | ... |
... | @@ -22,7 +22,10 @@ import org.onosproject.net.HostId; | ... | @@ -22,7 +22,10 @@ import org.onosproject.net.HostId; |
22 | import org.onosproject.net.region.Region; | 22 | import org.onosproject.net.region.Region; |
23 | import org.onosproject.net.region.RegionId; | 23 | import org.onosproject.net.region.RegionId; |
24 | 24 | ||
25 | +import java.util.ArrayList; | ||
26 | +import java.util.Collections; | ||
25 | import java.util.HashSet; | 27 | import java.util.HashSet; |
28 | +import java.util.List; | ||
26 | import java.util.Set; | 29 | import java.util.Set; |
27 | 30 | ||
28 | import static com.google.common.base.MoreObjects.toStringHelper; | 31 | import static com.google.common.base.MoreObjects.toStringHelper; |
... | @@ -37,6 +40,8 @@ public class UiRegion extends UiNode { | ... | @@ -37,6 +40,8 @@ public class UiRegion extends UiNode { |
37 | private final Set<HostId> hostIds = new HashSet<>(); | 40 | private final Set<HostId> hostIds = new HashSet<>(); |
38 | private final Set<UiLinkId> uiLinkIds = new HashSet<>(); | 41 | private final Set<UiLinkId> uiLinkIds = new HashSet<>(); |
39 | 42 | ||
43 | + private final List<String> layerOrder = new ArrayList<>(); | ||
44 | + | ||
40 | private final UiTopology topology; | 45 | private final UiTopology topology; |
41 | 46 | ||
42 | private final Region region; | 47 | private final Region region; |
... | @@ -50,6 +55,8 @@ public class UiRegion extends UiNode { | ... | @@ -50,6 +55,8 @@ public class UiRegion extends UiNode { |
50 | public UiRegion(UiTopology topology, Region region) { | 55 | public UiRegion(UiTopology topology, Region region) { |
51 | this.topology = topology; | 56 | this.topology = topology; |
52 | this.region = region; | 57 | this.region = region; |
58 | + // unless told otherwise, we'll use a single, default layer | ||
59 | + layerOrder.add(UiNode.LAYER_DEFAULT); | ||
53 | } | 60 | } |
54 | 61 | ||
55 | @Override | 62 | @Override |
... | @@ -60,6 +67,17 @@ public class UiRegion extends UiNode { | ... | @@ -60,6 +67,17 @@ public class UiRegion extends UiNode { |
60 | } | 67 | } |
61 | 68 | ||
62 | /** | 69 | /** |
70 | + * Sets the layer order for this region. | ||
71 | + * Typically, the {@code UiNode.LAYER_*} constants will be used here. | ||
72 | + * | ||
73 | + * @param layers the layers | ||
74 | + */ | ||
75 | + public void setLayerOrder(String... layers) { | ||
76 | + layerOrder.clear(); | ||
77 | + Collections.addAll(layerOrder, layers); | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
63 | * Returns the identity of the region. | 81 | * Returns the identity of the region. |
64 | * | 82 | * |
65 | * @return region ID | 83 | * @return region ID |
... | @@ -170,4 +188,19 @@ public class UiRegion extends UiNode { | ... | @@ -170,4 +188,19 @@ public class UiRegion extends UiNode { |
170 | public Set<UiLink> links() { | 188 | public Set<UiLink> links() { |
171 | return topology.linkSet(uiLinkIds); | 189 | return topology.linkSet(uiLinkIds); |
172 | } | 190 | } |
191 | + | ||
192 | + /** | ||
193 | + * Returns the order in which layers should be rendered. Lower layers | ||
194 | + * come earlier in the list. For example, to indicate that nodes in the | ||
195 | + * optical layer should be rendered "below" nodes in the packet layer, | ||
196 | + * this method should return: | ||
197 | + * <pre> | ||
198 | + * [UiNode.LAYER_OPTICAL, UiNode.LAYER_PACKET] | ||
199 | + * </pre> | ||
200 | + * | ||
201 | + * @return layer ordering | ||
202 | + */ | ||
203 | + public List<String> layerOrder() { | ||
204 | + return Collections.unmodifiableList(layerOrder); | ||
205 | + } | ||
173 | } | 206 | } | ... | ... |
... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
17 | package org.onosproject.ui.model.topo; | 17 | package org.onosproject.ui.model.topo; |
18 | 18 | ||
19 | import org.onosproject.net.region.Region; | 19 | import org.onosproject.net.region.Region; |
20 | +import org.onosproject.net.region.RegionId; | ||
20 | 21 | ||
21 | /** | 22 | /** |
22 | * Represents a specific "subset" of the UI model of the network topology | 23 | * Represents a specific "subset" of the UI model of the network topology |
... | @@ -41,6 +42,11 @@ public class UiTopoLayout { | ... | @@ -41,6 +42,11 @@ public class UiTopoLayout { |
41 | this.parent = parent; | 42 | this.parent = parent; |
42 | } | 43 | } |
43 | 44 | ||
45 | + @Override | ||
46 | + public String toString() { | ||
47 | + return "{UiTopoLayout: " + id + "}"; | ||
48 | + } | ||
49 | + | ||
44 | /** | 50 | /** |
45 | * Returns the UI layout identifier. | 51 | * Returns the UI layout identifier. |
46 | * | 52 | * |
... | @@ -51,7 +57,8 @@ public class UiTopoLayout { | ... | @@ -51,7 +57,8 @@ public class UiTopoLayout { |
51 | } | 57 | } |
52 | 58 | ||
53 | /** | 59 | /** |
54 | - * Returns the backing region with which this layout is associated. | 60 | + * Returns the backing region with which this layout is associated. Note |
61 | + * that this may be null (for the root layout). | ||
55 | * | 62 | * |
56 | * @return backing region | 63 | * @return backing region |
57 | */ | 64 | */ |
... | @@ -60,6 +67,16 @@ public class UiTopoLayout { | ... | @@ -60,6 +67,16 @@ public class UiTopoLayout { |
60 | } | 67 | } |
61 | 68 | ||
62 | /** | 69 | /** |
70 | + * Returns the identifier of the backing region. Will be null if the | ||
71 | + * region is null. | ||
72 | + * | ||
73 | + * @return backing region identifier | ||
74 | + */ | ||
75 | + public RegionId regionId() { | ||
76 | + return region == null ? null : region.id(); | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
63 | * Returns the parent layout identifier. | 80 | * Returns the parent layout identifier. |
64 | * | 81 | * |
65 | * @return parent layout identifier | 82 | * @return parent layout identifier | ... | ... |
... | @@ -23,8 +23,12 @@ import org.onosproject.net.region.RegionId; | ... | @@ -23,8 +23,12 @@ import org.onosproject.net.region.RegionId; |
23 | import org.slf4j.Logger; | 23 | import org.slf4j.Logger; |
24 | import org.slf4j.LoggerFactory; | 24 | import org.slf4j.LoggerFactory; |
25 | 25 | ||
26 | +import java.util.ArrayList; | ||
27 | +import java.util.Collections; | ||
28 | +import java.util.Comparator; | ||
26 | import java.util.HashMap; | 29 | import java.util.HashMap; |
27 | import java.util.HashSet; | 30 | import java.util.HashSet; |
31 | +import java.util.List; | ||
28 | import java.util.Map; | 32 | import java.util.Map; |
29 | import java.util.Set; | 33 | import java.util.Set; |
30 | 34 | ||
... | @@ -46,6 +50,9 @@ public class UiTopology extends UiElement { | ... | @@ -46,6 +50,9 @@ public class UiTopology extends UiElement { |
46 | 50 | ||
47 | private static final Logger log = LoggerFactory.getLogger(UiTopology.class); | 51 | private static final Logger log = LoggerFactory.getLogger(UiTopology.class); |
48 | 52 | ||
53 | + private static final Comparator<UiClusterMember> CLUSTER_MEMBER_COMPARATOR = | ||
54 | + (o1, o2) -> o1.idAsString().compareTo(o2.idAsString()); | ||
55 | + | ||
49 | 56 | ||
50 | // top level mappings of topology elements by ID | 57 | // top level mappings of topology elements by ID |
51 | private final Map<NodeId, UiClusterMember> cnodeLookup = new HashMap<>(); | 58 | private final Map<NodeId, UiClusterMember> cnodeLookup = new HashMap<>(); |
... | @@ -84,6 +91,18 @@ public class UiTopology extends UiElement { | ... | @@ -84,6 +91,18 @@ public class UiTopology extends UiElement { |
84 | linkLookup.clear(); | 91 | linkLookup.clear(); |
85 | } | 92 | } |
86 | 93 | ||
94 | + | ||
95 | + /** | ||
96 | + * Returns all the cluster members, sorted by their ID. | ||
97 | + * | ||
98 | + * @return all cluster members | ||
99 | + */ | ||
100 | + public List<UiClusterMember> allClusterMembers() { | ||
101 | + List<UiClusterMember> members = new ArrayList<>(cnodeLookup.values()); | ||
102 | + Collections.sort(members, CLUSTER_MEMBER_COMPARATOR); | ||
103 | + return members; | ||
104 | + } | ||
105 | + | ||
87 | /** | 106 | /** |
88 | * Returns the cluster member with the given identifier, or null if no | 107 | * Returns the cluster member with the given identifier, or null if no |
89 | * such member exists. | 108 | * such member exists. | ... | ... |
... | @@ -185,7 +185,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -185,7 +185,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
185 | private TimerTask summaryTask = null; | 185 | private TimerTask summaryTask = null; |
186 | private boolean summaryRunning = false; | 186 | private boolean summaryRunning = false; |
187 | 187 | ||
188 | - private boolean listenersRemoved = false; | 188 | + private volatile boolean listenersRemoved = false; |
189 | 189 | ||
190 | 190 | ||
191 | @Override | 191 | @Override | ... | ... |
... | @@ -32,7 +32,6 @@ import com.google.common.collect.ImmutableMap; | ... | @@ -32,7 +32,6 @@ import com.google.common.collect.ImmutableMap; |
32 | import com.google.common.collect.ImmutableSet; | 32 | import com.google.common.collect.ImmutableSet; |
33 | import com.google.common.collect.Lists; | 33 | import com.google.common.collect.Lists; |
34 | import com.google.common.collect.Maps; | 34 | import com.google.common.collect.Maps; |
35 | - | ||
36 | import org.apache.felix.scr.annotations.Activate; | 35 | import org.apache.felix.scr.annotations.Activate; |
37 | import org.apache.felix.scr.annotations.Component; | 36 | import org.apache.felix.scr.annotations.Component; |
38 | import org.apache.felix.scr.annotations.Deactivate; | 37 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -51,11 +50,12 @@ import org.onosproject.ui.UiExtension; | ... | @@ -51,11 +50,12 @@ import org.onosproject.ui.UiExtension; |
51 | import org.onosproject.ui.UiExtensionService; | 50 | import org.onosproject.ui.UiExtensionService; |
52 | import org.onosproject.ui.UiMessageHandlerFactory; | 51 | import org.onosproject.ui.UiMessageHandlerFactory; |
53 | import org.onosproject.ui.UiPreferencesService; | 52 | import org.onosproject.ui.UiPreferencesService; |
54 | -import org.onosproject.ui.UiTopoOverlayFactory; | 53 | +import org.onosproject.ui.UiTopoMap; |
55 | import org.onosproject.ui.UiTopoMapFactory; | 54 | import org.onosproject.ui.UiTopoMapFactory; |
55 | +import org.onosproject.ui.UiTopoOverlayFactory; | ||
56 | import org.onosproject.ui.UiView; | 56 | import org.onosproject.ui.UiView; |
57 | import org.onosproject.ui.UiViewHidden; | 57 | import org.onosproject.ui.UiViewHidden; |
58 | -import org.onosproject.ui.UiTopoMap; | 58 | +import org.onosproject.ui.impl.topo.Topo2ViewMessageHandler; |
59 | import org.slf4j.Logger; | 59 | import org.slf4j.Logger; |
60 | import org.slf4j.LoggerFactory; | 60 | import org.slf4j.LoggerFactory; |
61 | 61 | ||
... | @@ -120,7 +120,8 @@ public class UiExtensionManager | ... | @@ -120,7 +120,8 @@ public class UiExtensionManager |
120 | private final ObjectMapper mapper = new ObjectMapper(); | 120 | private final ObjectMapper mapper = new ObjectMapper(); |
121 | 121 | ||
122 | private final ExecutorService eventHandlingExecutor = | 122 | private final ExecutorService eventHandlingExecutor = |
123 | - Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/ui-ext-manager", "event-handler", log)); | 123 | + Executors.newSingleThreadExecutor( |
124 | + Tools.groupedThreads("onos/ui-ext-manager", "event-handler", log)); | ||
124 | 125 | ||
125 | // Creates core UI extension | 126 | // Creates core UI extension |
126 | private UiExtension createCoreExtension() { | 127 | private UiExtension createCoreExtension() { |
... | @@ -130,6 +131,10 @@ public class UiExtensionManager | ... | @@ -130,6 +131,10 @@ public class UiExtensionManager |
130 | new UiView(PLATFORM, "cluster", "Cluster Nodes", "nav_cluster"), | 131 | new UiView(PLATFORM, "cluster", "Cluster Nodes", "nav_cluster"), |
131 | new UiView(PLATFORM, "processor", "Packet Processors", "nav_processors"), | 132 | new UiView(PLATFORM, "processor", "Packet Processors", "nav_processors"), |
132 | new UiView(NETWORK, "topo", "Topology", "nav_topo"), | 133 | new UiView(NETWORK, "topo", "Topology", "nav_topo"), |
134 | + | ||
135 | + // FIXME: leave commented out for now, while still under development | ||
136 | +// new UiView(NETWORK, "topo2", "New-Topo"), | ||
137 | + | ||
133 | new UiView(NETWORK, "device", "Devices", "nav_devs"), | 138 | new UiView(NETWORK, "device", "Devices", "nav_devs"), |
134 | new UiViewHidden("flow"), | 139 | new UiViewHidden("flow"), |
135 | new UiViewHidden("port"), | 140 | new UiViewHidden("port"), |
... | @@ -145,6 +150,7 @@ public class UiExtensionManager | ... | @@ -145,6 +150,7 @@ public class UiExtensionManager |
145 | () -> ImmutableList.of( | 150 | () -> ImmutableList.of( |
146 | new UserPreferencesMessageHandler(), | 151 | new UserPreferencesMessageHandler(), |
147 | new TopologyViewMessageHandler(), | 152 | new TopologyViewMessageHandler(), |
153 | + new Topo2ViewMessageHandler(), | ||
148 | new MapSelectorMessageHandler(), | 154 | new MapSelectorMessageHandler(), |
149 | new DeviceViewMessageHandler(), | 155 | new DeviceViewMessageHandler(), |
150 | new LinkViewMessageHandler(), | 156 | new LinkViewMessageHandler(), |
... | @@ -196,11 +202,11 @@ public class UiExtensionManager | ... | @@ -196,11 +202,11 @@ public class UiExtensionManager |
196 | @Activate | 202 | @Activate |
197 | public void activate() { | 203 | public void activate() { |
198 | Serializer serializer = Serializer.using(KryoNamespaces.API, | 204 | Serializer serializer = Serializer.using(KryoNamespaces.API, |
199 | - ObjectNode.class, ArrayNode.class, | 205 | + ObjectNode.class, ArrayNode.class, |
200 | - JsonNodeFactory.class, LinkedHashMap.class, | 206 | + JsonNodeFactory.class, LinkedHashMap.class, |
201 | - TextNode.class, BooleanNode.class, | 207 | + TextNode.class, BooleanNode.class, |
202 | - LongNode.class, DoubleNode.class, ShortNode.class, | 208 | + LongNode.class, DoubleNode.class, ShortNode.class, |
203 | - IntNode.class, NullNode.class); | 209 | + IntNode.class, NullNode.class); |
204 | 210 | ||
205 | prefsConsistentMap = storageService.<String, ObjectNode>consistentMapBuilder() | 211 | prefsConsistentMap = storageService.<String, ObjectNode>consistentMapBuilder() |
206 | .withName(ONOS_USER_PREFERENCES) | 212 | .withName(ONOS_USER_PREFERENCES) | ... | ... |
... | @@ -92,7 +92,7 @@ public class UiWebSocket | ... | @@ -92,7 +92,7 @@ public class UiWebSocket |
92 | this.userName = userName; | 92 | this.userName = userName; |
93 | this.topoSession = | 93 | this.topoSession = |
94 | new UiTopoSession(this, directory.get(UiSharedTopologyModel.class), | 94 | new UiTopoSession(this, directory.get(UiSharedTopologyModel.class), |
95 | - directory.get(UiTopoLayoutService.class)); | 95 | + directory.get(UiTopoLayoutService.class)); |
96 | } | 96 | } |
97 | 97 | ||
98 | @Override | 98 | @Override |
... | @@ -122,6 +122,15 @@ public class UiWebSocket | ... | @@ -122,6 +122,15 @@ public class UiWebSocket |
122 | } | 122 | } |
123 | 123 | ||
124 | /** | 124 | /** |
125 | + * Provides a reference to the topology session. | ||
126 | + * | ||
127 | + * @return topo session reference | ||
128 | + */ | ||
129 | + public UiTopoSession topoSession() { | ||
130 | + return topoSession; | ||
131 | + } | ||
132 | + | ||
133 | + /** | ||
125 | * Issues a close on the connection. | 134 | * Issues a close on the connection. |
126 | */ | 135 | */ |
127 | synchronized void close() { | 136 | synchronized void close() { |
... | @@ -175,7 +184,7 @@ public class UiWebSocket | ... | @@ -175,7 +184,7 @@ public class UiWebSocket |
175 | topoSession.destroy(); | 184 | topoSession.destroy(); |
176 | destroyHandlersAndOverlays(); | 185 | destroyHandlersAndOverlays(); |
177 | log.info("GUI client disconnected [close-code={}, message={}]", | 186 | log.info("GUI client disconnected [close-code={}, message={}]", |
178 | - closeCode, message); | 187 | + closeCode, message); |
179 | } | 188 | } |
180 | 189 | ||
181 | @Override | 190 | @Override |
... | @@ -186,13 +195,13 @@ public class UiWebSocket | ... | @@ -186,13 +195,13 @@ public class UiWebSocket |
186 | 195 | ||
187 | @Override | 196 | @Override |
188 | public void onMessage(String data) { | 197 | public void onMessage(String data) { |
189 | - log.debug("onMessage: {}", data); | ||
190 | lastActive = System.currentTimeMillis(); | 198 | lastActive = System.currentTimeMillis(); |
191 | try { | 199 | try { |
192 | ObjectNode message = (ObjectNode) mapper.reader().readTree(data); | 200 | ObjectNode message = (ObjectNode) mapper.reader().readTree(data); |
193 | String type = message.path(EVENT).asText(UNKNOWN); | 201 | String type = message.path(EVENT).asText(UNKNOWN); |
194 | UiMessageHandler handler = handlers.get(type); | 202 | UiMessageHandler handler = handlers.get(type); |
195 | if (handler != null) { | 203 | if (handler != null) { |
204 | + log.debug("RX message: {}", message); | ||
196 | handler.process(message); | 205 | handler.process(message); |
197 | } else { | 206 | } else { |
198 | log.warn("No GUI message handler for type {}", type); | 207 | log.warn("No GUI message handler for type {}", type); |
... | @@ -208,6 +217,7 @@ public class UiWebSocket | ... | @@ -208,6 +217,7 @@ public class UiWebSocket |
208 | try { | 217 | try { |
209 | if (connection.isOpen()) { | 218 | if (connection.isOpen()) { |
210 | connection.sendMessage(message.toString()); | 219 | connection.sendMessage(message.toString()); |
220 | + log.debug("TX message: {}", message); | ||
211 | } | 221 | } |
212 | } catch (IOException e) { | 222 | } catch (IOException e) { |
213 | log.warn("Unable to send message {} to GUI due to {}", message, e); | 223 | log.warn("Unable to send message {} to GUI due to {}", message, e); |
... | @@ -257,7 +267,7 @@ public class UiWebSocket | ... | @@ -257,7 +267,7 @@ public class UiWebSocket |
257 | } | 267 | } |
258 | }); | 268 | }); |
259 | log.debug("#handlers = {}, #overlays = {}", handlers.size(), | 269 | log.debug("#handlers = {}, #overlays = {}", handlers.size(), |
260 | - overlayCache.size()); | 270 | + overlayCache.size()); |
261 | } | 271 | } |
262 | 272 | ||
263 | // Destroys message handlers. | 273 | // Destroys message handlers. |
... | @@ -284,7 +294,7 @@ public class UiWebSocket | ... | @@ -284,7 +294,7 @@ public class UiWebSocket |
284 | .put(ID, node.id().toString()) | 294 | .put(ID, node.id().toString()) |
285 | .put(IP, node.ip().toString()) | 295 | .put(IP, node.ip().toString()) |
286 | .put(TopoConstants.Glyphs.UI_ATTACHED, | 296 | .put(TopoConstants.Glyphs.UI_ATTACHED, |
287 | - node.equals(service.getLocalNode())); | 297 | + node.equals(service.getLocalNode())); |
288 | instances.add(instance); | 298 | instances.add(instance); |
289 | } | 299 | } |
290 | 300 | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.ui.impl.topo; | ||
18 | + | ||
19 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
21 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
22 | +import org.onlab.osgi.ServiceDirectory; | ||
23 | +import org.onosproject.cluster.ClusterService; | ||
24 | +import org.onosproject.cluster.NodeId; | ||
25 | +import org.onosproject.incubator.net.PortStatisticsService; | ||
26 | +import org.onosproject.incubator.net.tunnel.TunnelService; | ||
27 | +import org.onosproject.mastership.MastershipService; | ||
28 | +import org.onosproject.net.device.DeviceService; | ||
29 | +import org.onosproject.net.flow.FlowRuleService; | ||
30 | +import org.onosproject.net.host.HostService; | ||
31 | +import org.onosproject.net.intent.IntentService; | ||
32 | +import org.onosproject.net.link.LinkService; | ||
33 | +import org.onosproject.net.region.Region; | ||
34 | +import org.onosproject.net.statistic.StatisticService; | ||
35 | +import org.onosproject.net.topology.TopologyService; | ||
36 | +import org.onosproject.ui.model.topo.UiClusterMember; | ||
37 | +import org.onosproject.ui.model.topo.UiDevice; | ||
38 | +import org.onosproject.ui.model.topo.UiHost; | ||
39 | +import org.onosproject.ui.model.topo.UiLink; | ||
40 | +import org.onosproject.ui.model.topo.UiRegion; | ||
41 | +import org.onosproject.ui.model.topo.UiTopoLayout; | ||
42 | + | ||
43 | +import java.util.List; | ||
44 | + | ||
45 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
46 | + | ||
47 | +/** | ||
48 | + * Facility for creating JSON messages to send to the topology view in the | ||
49 | + * Web client. | ||
50 | + */ | ||
51 | +class Topo2Jsonifier { | ||
52 | + | ||
53 | + private final ObjectMapper mapper = new ObjectMapper(); | ||
54 | + | ||
55 | + private ServiceDirectory directory; | ||
56 | + private ClusterService clusterService; | ||
57 | + private DeviceService deviceService; | ||
58 | + private LinkService linkService; | ||
59 | + private HostService hostService; | ||
60 | + private MastershipService mastershipService; | ||
61 | + private IntentService intentService; | ||
62 | + private FlowRuleService flowService; | ||
63 | + private StatisticService flowStatsService; | ||
64 | + private PortStatisticsService portStatsService; | ||
65 | + private TopologyService topologyService; | ||
66 | + private TunnelService tunnelService; | ||
67 | + | ||
68 | + | ||
69 | + /** | ||
70 | + * Creates an instance with a reference to the services directory, so that | ||
71 | + * additional information about network elements may be looked up on | ||
72 | + * on the fly. | ||
73 | + * | ||
74 | + * @param directory service directory | ||
75 | + */ | ||
76 | + Topo2Jsonifier(ServiceDirectory directory) { | ||
77 | + this.directory = checkNotNull(directory, "Directory cannot be null"); | ||
78 | + | ||
79 | + clusterService = directory.get(ClusterService.class); | ||
80 | + deviceService = directory.get(DeviceService.class); | ||
81 | + linkService = directory.get(LinkService.class); | ||
82 | + hostService = directory.get(HostService.class); | ||
83 | + mastershipService = directory.get(MastershipService.class); | ||
84 | + intentService = directory.get(IntentService.class); | ||
85 | + flowService = directory.get(FlowRuleService.class); | ||
86 | + flowStatsService = directory.get(StatisticService.class); | ||
87 | + portStatsService = directory.get(PortStatisticsService.class); | ||
88 | + topologyService = directory.get(TopologyService.class); | ||
89 | + tunnelService = directory.get(TunnelService.class); | ||
90 | + | ||
91 | + } | ||
92 | + | ||
93 | + private ObjectNode objectNode() { | ||
94 | + return mapper.createObjectNode(); | ||
95 | + } | ||
96 | + | ||
97 | + private ArrayNode arrayNode() { | ||
98 | + return mapper.createArrayNode(); | ||
99 | + } | ||
100 | + | ||
101 | + private String nullIsEmpty(Object o) { | ||
102 | + return o == null ? "" : o.toString(); | ||
103 | + } | ||
104 | + | ||
105 | + | ||
106 | + /** | ||
107 | + * Returns a JSON representation of the cluster members (ONOS instances). | ||
108 | + * | ||
109 | + * @param instances the instance model objects | ||
110 | + * @return a JSON representation of the data | ||
111 | + */ | ||
112 | + ObjectNode instances(List<UiClusterMember> instances) { | ||
113 | + NodeId local = clusterService.getLocalNode().id(); | ||
114 | + ObjectNode payload = objectNode(); | ||
115 | + | ||
116 | + ArrayNode members = arrayNode(); | ||
117 | + payload.set("members", members); | ||
118 | + for (UiClusterMember member : instances) { | ||
119 | + members.add(json(member, member.id().equals(local))); | ||
120 | + } | ||
121 | + | ||
122 | + return payload; | ||
123 | + } | ||
124 | + | ||
125 | + private ObjectNode json(UiClusterMember member, boolean isUiAttached) { | ||
126 | + return objectNode() | ||
127 | + .put("id", member.id().toString()) | ||
128 | + .put("ip", member.ip().toString()) | ||
129 | + .put("online", member.isOnline()) | ||
130 | + .put("ready", member.isReady()) | ||
131 | + .put("uiAttached", isUiAttached) | ||
132 | + .put("switches", member.deviceCount()); | ||
133 | + } | ||
134 | + | ||
135 | + /** | ||
136 | + * Returns a JSON representation of the layout to use for displaying in | ||
137 | + * the topology view. | ||
138 | + * | ||
139 | + * @param layout the layout to transform | ||
140 | + * @return a JSON representation of the data | ||
141 | + */ | ||
142 | + ObjectNode layout(UiTopoLayout layout) { | ||
143 | + return objectNode() | ||
144 | + .put("id", layout.id().toString()) | ||
145 | + .put("parent", nullIsEmpty(layout.parent())) | ||
146 | + .put("region", nullIsEmpty(layout.regionId())) | ||
147 | + .put("regionName", regionName(layout.region())); | ||
148 | + } | ||
149 | + | ||
150 | + private String regionName(Region region) { | ||
151 | + return region == null ? "" : region.name(); | ||
152 | + } | ||
153 | + | ||
154 | + /** | ||
155 | + * Returns a JSON representation of the region to display in the topology | ||
156 | + * view. | ||
157 | + * | ||
158 | + * @param region the region to transform to JSON | ||
159 | + * @return a JSON representation of the data | ||
160 | + */ | ||
161 | + ObjectNode region(UiRegion region) { | ||
162 | + ObjectNode payload = objectNode(); | ||
163 | + | ||
164 | + if (region == null) { | ||
165 | + payload.put("note", "no-region"); | ||
166 | + return payload; | ||
167 | + } | ||
168 | + | ||
169 | + payload.put("id", region.id().toString()); | ||
170 | + | ||
171 | + ArrayNode layerOrder = arrayNode(); | ||
172 | + payload.set("layerOrder", layerOrder); | ||
173 | + region.layerOrder().forEach(layerOrder::add); | ||
174 | + | ||
175 | + ArrayNode devices = arrayNode(); | ||
176 | + payload.set("devices", devices); | ||
177 | + for (UiDevice device : region.devices()) { | ||
178 | + devices.add(json(device)); | ||
179 | + } | ||
180 | + | ||
181 | + ArrayNode hosts = arrayNode(); | ||
182 | + payload.set("hosts", hosts); | ||
183 | + for (UiHost host : region.hosts()) { | ||
184 | + hosts.add(json(host)); | ||
185 | + } | ||
186 | + | ||
187 | + ArrayNode links = arrayNode(); | ||
188 | + payload.set("links", links); | ||
189 | + for (UiLink link : region.links()) { | ||
190 | + links.add(json(link)); | ||
191 | + } | ||
192 | + | ||
193 | + return payload; | ||
194 | + } | ||
195 | + | ||
196 | + private ObjectNode json(UiDevice device) { | ||
197 | + ObjectNode node = objectNode() | ||
198 | + .put("id", device.id().toString()) | ||
199 | + .put("type", device.type()) | ||
200 | + .put("online", device.isOnline()) | ||
201 | + .put("master", device.master().toString()) | ||
202 | + .put("layer", device.layer()); | ||
203 | + | ||
204 | + // TODO: complete device details | ||
205 | +// addLabels(node, device); | ||
206 | +// addProps(node, device); | ||
207 | +// addGeoLocation(node, device); | ||
208 | +// addMetaUi(node, device); | ||
209 | + | ||
210 | + return node; | ||
211 | + } | ||
212 | + | ||
213 | + private void addLabels(ObjectNode node, UiDevice device) { | ||
214 | + | ||
215 | + } | ||
216 | + | ||
217 | + private ObjectNode json(UiHost host) { | ||
218 | + return objectNode() | ||
219 | + .put("id", host.id().toString()) | ||
220 | + .put("layer", host.layer()); | ||
221 | + // TODO: complete host details | ||
222 | + } | ||
223 | + | ||
224 | + | ||
225 | + private ObjectNode json(UiLink link) { | ||
226 | + return objectNode() | ||
227 | + .put("id", link.id().toString()); | ||
228 | + // TODO: complete link details | ||
229 | + } | ||
230 | + | ||
231 | + | ||
232 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.ui.impl.topo; | ||
18 | + | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | +import com.google.common.collect.ImmutableSet; | ||
21 | +import org.onlab.osgi.ServiceDirectory; | ||
22 | +import org.onosproject.ui.RequestHandler; | ||
23 | +import org.onosproject.ui.UiConnection; | ||
24 | +import org.onosproject.ui.UiMessageHandler; | ||
25 | +import org.onosproject.ui.impl.UiWebSocket; | ||
26 | +import org.onosproject.ui.model.topo.UiClusterMember; | ||
27 | +import org.onosproject.ui.model.topo.UiRegion; | ||
28 | +import org.onosproject.ui.model.topo.UiTopoLayout; | ||
29 | +import org.slf4j.Logger; | ||
30 | +import org.slf4j.LoggerFactory; | ||
31 | + | ||
32 | +import java.util.Collection; | ||
33 | +import java.util.List; | ||
34 | + | ||
35 | +/* | ||
36 | + NOTES: | ||
37 | + | ||
38 | + The original topology view message handler was broken into two classes | ||
39 | + TopologyViewMessageHandler, and TopologyViewMessageHandlerBase. | ||
40 | + We do not need to follow that model necessarily. Starting with a | ||
41 | + single class, and breaking it apart later if necessary. | ||
42 | + | ||
43 | + Need to figure out the connection between this message handler and the | ||
44 | + new way of doing things with UiTopoSession... | ||
45 | + | ||
46 | + */ | ||
47 | + | ||
48 | +/** | ||
49 | + * Server-side component for interacting with the new "Region aware" topology | ||
50 | + * view in the Web UI. | ||
51 | + */ | ||
52 | +public class Topo2ViewMessageHandler extends UiMessageHandler { | ||
53 | + | ||
54 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
55 | + | ||
56 | + // === Inbound event identifiers | ||
57 | + private static final String TOPO2_START = "topo2Start"; | ||
58 | + private static final String TOPO2_STOP = "topo2Stop"; | ||
59 | + | ||
60 | + // === Outbound event identifiers | ||
61 | + private static final String CURRENT_LAYOUT = "topo2CurrentLayout"; | ||
62 | + private static final String CURRENT_REGION = "topo2CurrentRegion"; | ||
63 | + private static final String ALL_INSTANCES = "topo2AllInstances"; | ||
64 | + private static final String TOPO_START_DONE = "topo2StartDone"; | ||
65 | + | ||
66 | + private UiTopoSession topoSession; | ||
67 | + private Topo2Jsonifier t2json; | ||
68 | + | ||
69 | + | ||
70 | + @Override | ||
71 | + public void init(UiConnection connection, ServiceDirectory directory) { | ||
72 | + super.init(connection, directory); | ||
73 | + | ||
74 | + // get the topo session from the UiWebSocket | ||
75 | + topoSession = ((UiWebSocket) connection).topoSession(); | ||
76 | + t2json = new Topo2Jsonifier(directory); | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + protected Collection<RequestHandler> createRequestHandlers() { | ||
81 | + return ImmutableSet.of( | ||
82 | + new Topo2Start(), | ||
83 | + new Topo2Stop() | ||
84 | + ); | ||
85 | + } | ||
86 | + | ||
87 | + // ================================================================== | ||
88 | + | ||
89 | + | ||
90 | + private final class Topo2Start extends RequestHandler { | ||
91 | + private Topo2Start() { | ||
92 | + super(TOPO2_START); | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public void process(long sid, ObjectNode payload) { | ||
97 | + // client view is ready to receive data to display; so start up | ||
98 | + // server-side processing, and send over initial state | ||
99 | + | ||
100 | + log.debug("topo2Start: {}", payload); | ||
101 | + | ||
102 | + List<UiClusterMember> instances = topoSession.getAllInstances(); | ||
103 | + sendMessage(ALL_INSTANCES, t2json.instances(instances)); | ||
104 | + | ||
105 | + UiTopoLayout currentLayout = topoSession.currentLayout(); | ||
106 | + sendMessage(CURRENT_LAYOUT, t2json.layout(currentLayout)); | ||
107 | + | ||
108 | + UiRegion region = topoSession.getRegion(currentLayout); | ||
109 | + sendMessage(CURRENT_REGION, t2json.region(region)); | ||
110 | + | ||
111 | + // TODO: send information about devices/hosts/links in non-region | ||
112 | + // TODO: send information about "linked, peer" regions | ||
113 | + | ||
114 | + sendMessage(TOPO_START_DONE, null); | ||
115 | + | ||
116 | + | ||
117 | + // OLD CODE DID THE FOLLOWING... | ||
118 | +// addListeners(); | ||
119 | +// sendAllInstances(null); | ||
120 | +// sendAllDevices(); | ||
121 | +// sendAllLinks(); | ||
122 | +// sendAllHosts(); | ||
123 | +// sendTopoStartDone(); | ||
124 | + } | ||
125 | + } | ||
126 | + | ||
127 | + private final class Topo2Stop extends RequestHandler { | ||
128 | + private Topo2Stop() { | ||
129 | + super(TOPO2_STOP); | ||
130 | + } | ||
131 | + | ||
132 | + @Override | ||
133 | + public void process(long sid, ObjectNode payload) { | ||
134 | + // client view has gone away; so shut down server-side processing | ||
135 | + // TODO: implement... | ||
136 | + | ||
137 | + log.debug("topo2Stop: {}", payload); | ||
138 | + | ||
139 | + // OLD CODE DID THE FOLLOWING... | ||
140 | +// removeListeners(); | ||
141 | +// stopSummaryMonitoring(); | ||
142 | +// traffic.stopMonitoring(); | ||
143 | + } | ||
144 | + } | ||
145 | + | ||
146 | +} |
... | @@ -21,10 +21,14 @@ import org.onosproject.ui.impl.UiWebSocket; | ... | @@ -21,10 +21,14 @@ import org.onosproject.ui.impl.UiWebSocket; |
21 | import org.onosproject.ui.impl.topo.model.UiModelEvent; | 21 | import org.onosproject.ui.impl.topo.model.UiModelEvent; |
22 | import org.onosproject.ui.impl.topo.model.UiModelListener; | 22 | import org.onosproject.ui.impl.topo.model.UiModelListener; |
23 | import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel; | 23 | import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel; |
24 | +import org.onosproject.ui.model.topo.UiClusterMember; | ||
25 | +import org.onosproject.ui.model.topo.UiRegion; | ||
24 | import org.onosproject.ui.model.topo.UiTopoLayout; | 26 | import org.onosproject.ui.model.topo.UiTopoLayout; |
25 | import org.slf4j.Logger; | 27 | import org.slf4j.Logger; |
26 | import org.slf4j.LoggerFactory; | 28 | import org.slf4j.LoggerFactory; |
27 | 29 | ||
30 | +import java.util.List; | ||
31 | + | ||
28 | /** | 32 | /** |
29 | * Coordinates with the {@link UiTopoLayoutService} to access | 33 | * Coordinates with the {@link UiTopoLayoutService} to access |
30 | * {@link UiTopoLayout}s, and with the {@link UiSharedTopologyModel} which | 34 | * {@link UiTopoLayout}s, and with the {@link UiSharedTopologyModel} which |
... | @@ -34,6 +38,10 @@ import org.slf4j.LoggerFactory; | ... | @@ -34,6 +38,10 @@ import org.slf4j.LoggerFactory; |
34 | * Note that an instance of this class will be created for each | 38 | * Note that an instance of this class will be created for each |
35 | * {@link UiWebSocket} connection, and will contain | 39 | * {@link UiWebSocket} connection, and will contain |
36 | * the state of how the topology is laid out for the logged-in user. | 40 | * the state of how the topology is laid out for the logged-in user. |
41 | + * <p> | ||
42 | + * The expected pattern is for the {@link Topo2ViewMessageHandler} to obtain | ||
43 | + * a reference to the session instance (via the {@link UiWebSocket}), and | ||
44 | + * interact with it when topo-related events come in from the client. | ||
37 | */ | 45 | */ |
38 | public class UiTopoSession implements UiModelListener { | 46 | public class UiTopoSession implements UiModelListener { |
39 | private final Logger log = LoggerFactory.getLogger(getClass()); | 47 | private final Logger log = LoggerFactory.getLogger(getClass()); |
... | @@ -129,4 +137,23 @@ public class UiTopoSession implements UiModelListener { | ... | @@ -129,4 +137,23 @@ public class UiTopoSession implements UiModelListener { |
129 | public void enableEvent(boolean enabled) { | 137 | public void enableEvent(boolean enabled) { |
130 | messagesEnabled = enabled; | 138 | messagesEnabled = enabled; |
131 | } | 139 | } |
140 | + | ||
141 | + /** | ||
142 | + * Returns the list of ONOS instances (cluster members). | ||
143 | + * | ||
144 | + * @return the list of ONOS instances | ||
145 | + */ | ||
146 | + public List<UiClusterMember> getAllInstances() { | ||
147 | + return sharedModel.getClusterMembers(); | ||
148 | + } | ||
149 | + | ||
150 | + /** | ||
151 | + * Returns the region for the specified layout. | ||
152 | + * | ||
153 | + * @param layout layout filter | ||
154 | + * @return region that the layout is based upon | ||
155 | + */ | ||
156 | + public UiRegion getRegion(UiTopoLayout layout) { | ||
157 | + return sharedModel.getRegion(layout); | ||
158 | + } | ||
132 | } | 159 | } | ... | ... |
... | @@ -41,6 +41,7 @@ import org.onosproject.ui.model.topo.UiTopology; | ... | @@ -41,6 +41,7 @@ import org.onosproject.ui.model.topo.UiTopology; |
41 | import org.slf4j.Logger; | 41 | import org.slf4j.Logger; |
42 | import org.slf4j.LoggerFactory; | 42 | import org.slf4j.LoggerFactory; |
43 | 43 | ||
44 | +import java.util.List; | ||
44 | import java.util.Set; | 45 | import java.util.Set; |
45 | 46 | ||
46 | import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; | 47 | import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; |
... | @@ -153,6 +154,10 @@ class ModelCache { | ... | @@ -153,6 +154,10 @@ class ModelCache { |
153 | } | 154 | } |
154 | } | 155 | } |
155 | 156 | ||
157 | + List<UiClusterMember> getAllClusterMembers() { | ||
158 | + return uiTopology.allClusterMembers(); | ||
159 | + } | ||
160 | + | ||
156 | 161 | ||
157 | // === MASTERSHIP CHANGES | 162 | // === MASTERSHIP CHANGES |
158 | 163 | ||
... | @@ -199,7 +204,7 @@ class ModelCache { | ... | @@ -199,7 +204,7 @@ class ModelCache { |
199 | 204 | ||
200 | // package private for unit test access | 205 | // package private for unit test access |
201 | UiRegion accessRegion(RegionId id) { | 206 | UiRegion accessRegion(RegionId id) { |
202 | - return uiTopology.findRegion(id); | 207 | + return id == null ? null : uiTopology.findRegion(id); |
203 | } | 208 | } |
204 | 209 | ||
205 | // invoked from UiSharedTopologyModel region listener | 210 | // invoked from UiSharedTopologyModel region listener |
... | @@ -484,4 +489,5 @@ class ModelCache { | ... | @@ -484,4 +489,5 @@ class ModelCache { |
484 | public int hostCount() { | 489 | public int hostCount() { |
485 | return uiTopology.hostCount(); | 490 | return uiTopology.hostCount(); |
486 | } | 491 | } |
492 | + | ||
487 | } | 493 | } | ... | ... |
... | @@ -16,9 +16,6 @@ | ... | @@ -16,9 +16,6 @@ |
16 | 16 | ||
17 | package org.onosproject.ui.impl.topo.model; | 17 | package org.onosproject.ui.impl.topo.model; |
18 | 18 | ||
19 | -import java.util.concurrent.ExecutorService; | ||
20 | -import java.util.concurrent.Executors; | ||
21 | - | ||
22 | import org.apache.felix.scr.annotations.Activate; | 19 | import org.apache.felix.scr.annotations.Activate; |
23 | import org.apache.felix.scr.annotations.Component; | 20 | import org.apache.felix.scr.annotations.Component; |
24 | import org.apache.felix.scr.annotations.Deactivate; | 21 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -64,9 +61,19 @@ import org.onosproject.net.statistic.StatisticService; | ... | @@ -64,9 +61,19 @@ import org.onosproject.net.statistic.StatisticService; |
64 | import org.onosproject.net.topology.TopologyService; | 61 | import org.onosproject.net.topology.TopologyService; |
65 | import org.onosproject.ui.impl.topo.UiTopoSession; | 62 | import org.onosproject.ui.impl.topo.UiTopoSession; |
66 | import org.onosproject.ui.model.ServiceBundle; | 63 | import org.onosproject.ui.model.ServiceBundle; |
64 | +import org.onosproject.ui.model.topo.UiClusterMember; | ||
65 | +import org.onosproject.ui.model.topo.UiElement; | ||
66 | +import org.onosproject.ui.model.topo.UiRegion; | ||
67 | +import org.onosproject.ui.model.topo.UiTopoLayout; | ||
67 | import org.slf4j.Logger; | 68 | import org.slf4j.Logger; |
68 | import org.slf4j.LoggerFactory; | 69 | import org.slf4j.LoggerFactory; |
69 | 70 | ||
71 | +import java.util.HashSet; | ||
72 | +import java.util.List; | ||
73 | +import java.util.Set; | ||
74 | +import java.util.concurrent.ExecutorService; | ||
75 | +import java.util.concurrent.Executors; | ||
76 | + | ||
70 | /** | 77 | /** |
71 | * Service that creates and maintains the UI-model of the network topology. | 78 | * Service that creates and maintains the UI-model of the network topology. |
72 | */ | 79 | */ |
... | @@ -190,6 +197,41 @@ public final class UiSharedTopologyModel | ... | @@ -190,6 +197,41 @@ public final class UiSharedTopologyModel |
190 | removeListener(session); | 197 | removeListener(session); |
191 | } | 198 | } |
192 | 199 | ||
200 | + | ||
201 | + // ======================================================================= | ||
202 | + // methods that the topo session will use to extract information from us | ||
203 | + | ||
204 | + /** | ||
205 | + * Returns the list of cluster members stored in our model cache. | ||
206 | + * | ||
207 | + * @return list of cluster members | ||
208 | + */ | ||
209 | + public List<UiClusterMember> getClusterMembers() { | ||
210 | + return cache.getAllClusterMembers(); | ||
211 | + } | ||
212 | + | ||
213 | + public Set<UiElement> getElements(UiTopoLayout layout) { | ||
214 | + Set<UiElement> results = new HashSet<>(); | ||
215 | + | ||
216 | + // TODO: figure out how to extract the appropriate nodes | ||
217 | + // from the cache, for the given layout. | ||
218 | + | ||
219 | + return results; | ||
220 | + } | ||
221 | + | ||
222 | + /** | ||
223 | + * Returns the region for the given layout. | ||
224 | + * | ||
225 | + * @param layout layout filter | ||
226 | + * @return the region the layout is based upon | ||
227 | + */ | ||
228 | + public UiRegion getRegion(UiTopoLayout layout) { | ||
229 | + return cache.accessRegion(layout.regionId()); | ||
230 | + } | ||
231 | + | ||
232 | + // ===================================================================== | ||
233 | + | ||
234 | + | ||
193 | /** | 235 | /** |
194 | * Default implementation of service bundle to return references to our | 236 | * Default implementation of service bundle to return references to our |
195 | * dynamically injected services. | 237 | * dynamically injected services. | ... | ... |
... | @@ -256,6 +256,8 @@ | ... | @@ -256,6 +256,8 @@ |
256 | }); | 256 | }); |
257 | } | 257 | } |
258 | 258 | ||
259 | + // TODO: simplify listener handling (see theme.js for sample code) | ||
260 | + | ||
259 | function addOpenListener(callback) { | 261 | function addOpenListener(callback) { |
260 | var id = nextListenerId++, | 262 | var id = nextListenerId++, |
261 | cb = fs.isF(callback), | 263 | cb = fs.isF(callback), | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | + | ||
18 | +/* | ||
19 | + ONOS GUI -- Topology View (theme) -- CSS file | ||
20 | + */ | ||
21 | + | ||
22 | +/* --- Base SVG Layer --- */ | ||
23 | + | ||
24 | +#ov-topo2 svg { | ||
25 | + /*background-color: #f4f4f4;*/ | ||
26 | + background-color: goldenrod; /* just for testing */ | ||
27 | +} | ||
28 | + | ||
29 | +/* --- "No Devices" Layer --- */ | ||
30 | + | ||
31 | +#ov-topo2 svg .noDevsBird { | ||
32 | + fill: #db7773; | ||
33 | +} | ||
34 | + | ||
35 | +#ov-topo2 svg #topo2-noDevsLayer text { | ||
36 | + fill: #7e9aa8; | ||
37 | +} | ||
38 | + | ||
39 | +/* --- Topo Map --- */ | ||
40 | + | ||
41 | +#ov-topo2 svg #topo2-map { | ||
42 | + stroke-width: 2px; | ||
43 | + stroke: #f4f4f4; | ||
44 | + fill: #e5e5e6; | ||
45 | +} | ||
46 | + |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | + | ||
18 | +/* | ||
19 | + ONOS GUI -- Topology View (layout) -- CSS file | ||
20 | + */ | ||
21 | + | ||
22 | +/* --- Base SVG Layer --- */ | ||
23 | + | ||
24 | +#ov-topo2 svg { | ||
25 | + /* prevents the little cut/copy/paste square that would appear on iPad */ | ||
26 | + -webkit-user-select: none; | ||
27 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- Topology View Module | ||
19 | + | ||
20 | + NOTE: currently under development to support Regions. | ||
21 | + */ | ||
22 | + | ||
23 | +(function () { | ||
24 | + 'use strict'; | ||
25 | + | ||
26 | + // references to injected services | ||
27 | + var $scope, $log, $loc, | ||
28 | + fs, mast, ks, zs, | ||
29 | + gs, ms, sus, flash, | ||
30 | + wss, ps, th, | ||
31 | + t2es, t2fs; | ||
32 | + | ||
33 | + // DOM elements | ||
34 | + var ovtopo2, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer; | ||
35 | + | ||
36 | + // Internal state | ||
37 | + var zoomer, actionMap; | ||
38 | + | ||
39 | + | ||
40 | + // === Helper Functions | ||
41 | + | ||
42 | + // callback invoked when the SVG view has been resized.. | ||
43 | + function svgResized(s) { | ||
44 | + $log.debug("topo2 view resized", s); | ||
45 | + } | ||
46 | + | ||
47 | + function setUpKeys(overlayKeys) { | ||
48 | + $log.debug('topo2: set up keys....'); | ||
49 | + } | ||
50 | + | ||
51 | + // === Controller Definition ----------------------------------------- | ||
52 | + | ||
53 | + angular.module('ovTopo2', ['onosUtil', 'onosSvg', 'onosRemote']) | ||
54 | + .controller('OvTopo2Ctrl', | ||
55 | + ['$scope', '$log', '$location', | ||
56 | + 'FnService', 'MastService', 'KeyService', 'ZoomService', | ||
57 | + 'GlyphService', 'MapService', 'SvgUtilService', 'FlashService', | ||
58 | + 'WebSocketService', 'PrefsService', 'ThemeService', | ||
59 | + 'Topo2EventService', 'Topo2ForceService', | ||
60 | + | ||
61 | + function (_$scope_, _$log_, _$loc_, | ||
62 | + _fs_, _mast_, _ks_, _zs_, | ||
63 | + _gs_, _ms_, _sus_, _flash_, | ||
64 | + _wss_, _ps_, _th_, | ||
65 | + _t2es_, _t2fs_) { | ||
66 | + | ||
67 | + var params = _$loc_.search(), | ||
68 | + projection, | ||
69 | + dim, | ||
70 | + wh, | ||
71 | + uplink = { | ||
72 | + // provides function calls back into this space | ||
73 | + // showNoDevs: showNoDevs, | ||
74 | + // projection: function () { return projection; }, | ||
75 | + // zoomLayer: function () { return zoomLayer; }, | ||
76 | + // zoomer: function () { return zoomer; }, | ||
77 | + // opacifyMap: opacifyMap, | ||
78 | + // topoStartDone: topoStartDone | ||
79 | + }; | ||
80 | + | ||
81 | + $scope = _$scope_; | ||
82 | + $log = _$log_; | ||
83 | + $loc = _$loc_; | ||
84 | + | ||
85 | + fs = _fs_; | ||
86 | + mast = _mast_; | ||
87 | + ks = _ks_; | ||
88 | + zs = _zs_; | ||
89 | + | ||
90 | + gs = _gs_; | ||
91 | + ms = _ms_; | ||
92 | + sus = _sus_; | ||
93 | + flash = _flash_; | ||
94 | + | ||
95 | + wss = _wss_; | ||
96 | + ps = _ps_; | ||
97 | + th = _th_; | ||
98 | + | ||
99 | + t2es = _t2es_; | ||
100 | + t2fs = _t2fs_; | ||
101 | + | ||
102 | + // capture selected intent parameters (if they are set in the | ||
103 | + // query string) so that the traffic overlay can highlight | ||
104 | + // the path for that intent | ||
105 | + if (params.intentKey && params.intentAppId && params.intentAppName) { | ||
106 | + $scope.intentData = { | ||
107 | + key: params.intentKey, | ||
108 | + appId: params.intentAppId, | ||
109 | + appName: params.intentAppName | ||
110 | + }; | ||
111 | + } | ||
112 | + | ||
113 | + $scope.notifyResize = function () { | ||
114 | + svgResized(fs.windowSize(mast.mastHeight())); | ||
115 | + }; | ||
116 | + | ||
117 | + // Cleanup on destroyed scope.. | ||
118 | + $scope.$on('$destroy', function () { | ||
119 | + $log.log('OvTopo2Ctrl is saying Buh-Bye!'); | ||
120 | + t2es.stop(); | ||
121 | + ks.unbindKeys(); | ||
122 | + t2fs.destroy(); | ||
123 | + }); | ||
124 | + | ||
125 | + // svg layer and initialization of components | ||
126 | + ovtopo2 = d3.select('#ov-topo2'); | ||
127 | + svg = ovtopo2.select('svg'); | ||
128 | + // set the svg size to match that of the window, less the masthead | ||
129 | + wh = fs.windowSize(mast.mastHeight()); | ||
130 | + $log.debug('setting topo SVG size to', wh); | ||
131 | + svg.attr(wh); | ||
132 | + dim = [wh.width, wh.height]; | ||
133 | + | ||
134 | + | ||
135 | + // set up our keyboard shortcut bindings | ||
136 | + setUpKeys(); | ||
137 | + | ||
138 | + // make sure we can respond to topology events from the server | ||
139 | + t2es.bindHandlers(); | ||
140 | + | ||
141 | + // initialize the force layout, ready to render the topology | ||
142 | + t2fs.init(); | ||
143 | + | ||
144 | + | ||
145 | + // =-=-=-=-=-=-=-=- | ||
146 | + // TODO: in future, we will load background map data | ||
147 | + // asynchronously (hence the promise) and then chain off | ||
148 | + // there to send the topo2start event to the server. | ||
149 | + // For now, we'll send the event inline... | ||
150 | + t2es.start(); | ||
151 | + | ||
152 | + | ||
153 | + // === ORIGINAL CODE === | ||
154 | + | ||
155 | + // setUpKeys(); | ||
156 | + // setUpToolbar(); | ||
157 | + // setUpDefs(); | ||
158 | + // setUpZoom(); | ||
159 | + // setUpNoDevs(); | ||
160 | + /* | ||
161 | + setUpMap().then( | ||
162 | + function (proj) { | ||
163 | + var z = ps.getPrefs('topo_zoom', { tx:0, ty:0, sc:1 }); | ||
164 | + zoomer.panZoom([z.tx, z.ty], z.sc); | ||
165 | + $log.debug('** Zoom restored:', z); | ||
166 | + | ||
167 | + projection = proj; | ||
168 | + $log.debug('** We installed the projection:', proj); | ||
169 | + flash.enable(false); | ||
170 | + toggleMap(prefsState.bg); | ||
171 | + flash.enable(true); | ||
172 | + mapShader(true); | ||
173 | + | ||
174 | + // now we have the map projection, we are ready for | ||
175 | + // the server to send us device/host data... | ||
176 | + tes.start(); | ||
177 | + // need to do the following so we immediately get | ||
178 | + // the summary panel data back from the server | ||
179 | + restoreSummaryFromPrefs(); | ||
180 | + } | ||
181 | + ); | ||
182 | + */ | ||
183 | + // tes.bindHandlers(); | ||
184 | + // setUpSprites(); | ||
185 | + | ||
186 | + // forceG = zoomLayer.append('g').attr('id', 'topo-force'); | ||
187 | + // tfs.initForce(svg, forceG, uplink, dim); | ||
188 | + // tis.initInst({ showMastership: tfs.showMastership }); | ||
189 | + // tps.initPanels(); | ||
190 | + | ||
191 | + // restoreConfigFromPrefs(); | ||
192 | + // ttbs.setDefaultOverlay(prefsState.ovidx); | ||
193 | + | ||
194 | + // $log.debug('registered overlays...', tov.list()); | ||
195 | + | ||
196 | + $log.log('OvTopo2Ctrl has been created'); | ||
197 | + }]); | ||
198 | +}()); |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- Topology Event Module. | ||
19 | + | ||
20 | + Defines the conduit between the client and the server: | ||
21 | + - provides a clean API for sending events to the server | ||
22 | + - dispatches incoming events from the server to the appropriate sub-module | ||
23 | + | ||
24 | + */ | ||
25 | + | ||
26 | +(function () { | ||
27 | + 'use strict'; | ||
28 | + | ||
29 | + // injected refs | ||
30 | + var $log, wss, t2fs; | ||
31 | + | ||
32 | + // internal state | ||
33 | + var handlerMap, | ||
34 | + openListener; | ||
35 | + | ||
36 | + // TODO: only add heartbeat timer etc. if we really need to be doing that.. | ||
37 | + | ||
38 | + // ========================== Helper Functions | ||
39 | + | ||
40 | + function createHandlerMap() { | ||
41 | + handlerMap = { | ||
42 | + topo2AllInstances: t2fs, | ||
43 | + topo2CurrentLayout: t2fs, | ||
44 | + topo2CurrentRegion: t2fs, | ||
45 | + topo2StartDone: t2fs | ||
46 | + | ||
47 | + // Add further event names / module references as needed | ||
48 | + }; | ||
49 | + } | ||
50 | + | ||
51 | + function wsOpen(host, url) { | ||
52 | + $log.debug('topo2Event: WSopen - cluster node:', host, 'URL:', url); | ||
53 | + // tell the server we are ready to receive topo events | ||
54 | + wss.sendEvent('topo2Start'); | ||
55 | + } | ||
56 | + | ||
57 | + // bind our event handlers to the web socket service, so that our | ||
58 | + // callbacks get invoked for incoming events | ||
59 | + function bindHandlers() { | ||
60 | + wss.bindHandlers(handlerMap); | ||
61 | + $log.debug('topo2 event handlers bound'); | ||
62 | + } | ||
63 | + | ||
64 | + // tell the server we are ready to receive topology events | ||
65 | + function start() { | ||
66 | + // in case we fail over to a new server, | ||
67 | + // listen for wsock-open events | ||
68 | + openListener = wss.addOpenListener(wsOpen); | ||
69 | + wss.sendEvent('topo2Start'); | ||
70 | + $log.debug('topo2 comms started'); | ||
71 | + } | ||
72 | + | ||
73 | + // tell the server we no longer wish to receive topology events | ||
74 | + function stop() { | ||
75 | + wss.sendEvent('topo2Stop'); | ||
76 | + wss.unbindHandlers(handlerMap); | ||
77 | + wss.removeOpenListener(openListener); | ||
78 | + openListener = null; | ||
79 | + $log.debug('topo2 comms stopped'); | ||
80 | + } | ||
81 | + | ||
82 | + // ========================== Main Service Definition | ||
83 | + | ||
84 | + angular.module('ovTopo2') | ||
85 | + .factory('Topo2EventService', | ||
86 | + ['$log', 'WebSocketService', 'Topo2ForceService', | ||
87 | + | ||
88 | + function (_$log_, _wss_, _t2fs_) { | ||
89 | + $log = _$log_; | ||
90 | + wss = _wss_; | ||
91 | + t2fs = _t2fs_; | ||
92 | + | ||
93 | + // deferred creation of handler map, so module references are good | ||
94 | + createHandlerMap(); | ||
95 | + | ||
96 | + return { | ||
97 | + bindHandlers: bindHandlers, | ||
98 | + start: start, | ||
99 | + stop: stop | ||
100 | + }; | ||
101 | + }]); | ||
102 | +}()); |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- Topology Force Module. | ||
19 | + Visualization of the topology in an SVG layer, using a D3 Force Layout. | ||
20 | + */ | ||
21 | + | ||
22 | +(function () { | ||
23 | + 'use strict'; | ||
24 | + | ||
25 | + // injected refs | ||
26 | + var $log, wss; | ||
27 | + | ||
28 | + // ========================== Helper Functions | ||
29 | + | ||
30 | + function init() { | ||
31 | + $log.debug('Initialize topo force layout'); | ||
32 | + } | ||
33 | + | ||
34 | + function destroy() { | ||
35 | + $log.debug('Destroy topo force layout'); | ||
36 | + } | ||
37 | + | ||
38 | + // ========================== Event Handlers | ||
39 | + | ||
40 | + function allInstances(data) { | ||
41 | + $log.debug('>> topo2AllInstances event:', data) | ||
42 | + } | ||
43 | + | ||
44 | + function currentLayout(data) { | ||
45 | + $log.debug('>> topo2CurrentLayout event:', data) | ||
46 | + } | ||
47 | + | ||
48 | + function currentRegion(data) { | ||
49 | + $log.debug('>> topo2CurrentRegion event:', data) | ||
50 | + } | ||
51 | + | ||
52 | + function startDone(data) { | ||
53 | + $log.debug('>> topo2StartDone event:', data) | ||
54 | + } | ||
55 | + | ||
56 | + // ========================== Main Service Definition | ||
57 | + | ||
58 | + angular.module('ovTopo2') | ||
59 | + .factory('Topo2ForceService', | ||
60 | + ['$log', 'WebSocketService', | ||
61 | + | ||
62 | + function (_$log_, _wss_) { | ||
63 | + $log = _$log_; | ||
64 | + wss = _wss_; | ||
65 | + | ||
66 | + return { | ||
67 | + init: init, | ||
68 | + destroy: destroy, | ||
69 | + topo2AllInstances: allInstances, | ||
70 | + topo2CurrentLayout: currentLayout, | ||
71 | + topo2CurrentRegion: currentRegion, | ||
72 | + topo2StartDone: startDone | ||
73 | + }; | ||
74 | + }]); | ||
75 | +}()); |
... | @@ -126,6 +126,13 @@ | ... | @@ -126,6 +126,13 @@ |
126 | <link rel="stylesheet" href="app/fw/widget/table.css"> | 126 | <link rel="stylesheet" href="app/fw/widget/table.css"> |
127 | <link rel="stylesheet" href="app/fw/widget/table-theme.css"> | 127 | <link rel="stylesheet" href="app/fw/widget/table-theme.css"> |
128 | 128 | ||
129 | + <!-- Under development for Region support. --> | ||
130 | + <script src="app/view/topo2/topo2.js"></script> | ||
131 | + <script src="app/view/topo2/topo2Event.js"></script> | ||
132 | + <script src="app/view/topo2/topo2Force.js"></script> | ||
133 | + <link rel="stylesheet" href="app/view/topo2/topo2.css"> | ||
134 | + <link rel="stylesheet" href="app/view/topo2/topo2-theme.css"> | ||
135 | + | ||
129 | <!-- Builtin views javascript. --> | 136 | <!-- Builtin views javascript. --> |
130 | <script src="app/view/topo/topo.js"></script> | 137 | <script src="app/view/topo/topo.js"></script> |
131 | <script src="app/view/topo/topoD3.js"></script> | 138 | <script src="app/view/topo/topoD3.js"></script> | ... | ... |
-
Please register or login to post a comment