Starting implementation of UI topo modeling. WIP.
If reviewing this, please refer to http://tinyurl.com/onos-ui-topo-model Change-Id: Iab75f213ca0a7d36619f9c498387b402ac9477af
Showing
6 changed files
with
275 additions
and
21 deletions
| ... | @@ -16,8 +16,12 @@ | ... | @@ -16,8 +16,12 @@ |
| 16 | 16 | ||
| 17 | package org.onosproject.ui.model.topo; | 17 | package org.onosproject.ui.model.topo; |
| 18 | 18 | ||
| 19 | +import org.onosproject.cluster.NodeId; | ||
| 20 | + | ||
| 19 | import java.util.ArrayList; | 21 | import java.util.ArrayList; |
| 22 | +import java.util.HashMap; | ||
| 20 | import java.util.List; | 23 | import java.util.List; |
| 24 | +import java.util.Map; | ||
| 21 | 25 | ||
| 22 | /** | 26 | /** |
| 23 | * Encapsulates the notion of the ONOS cluster. | 27 | * Encapsulates the notion of the ONOS cluster. |
| ... | @@ -25,6 +29,12 @@ import java.util.List; | ... | @@ -25,6 +29,12 @@ import java.util.List; |
| 25 | class UiCluster extends UiElement { | 29 | class UiCluster extends UiElement { |
| 26 | 30 | ||
| 27 | private final List<UiClusterMember> members = new ArrayList<>(); | 31 | private final List<UiClusterMember> members = new ArrayList<>(); |
| 32 | + private final Map<NodeId, UiClusterMember> lookup = new HashMap<>(); | ||
| 33 | + | ||
| 34 | + @Override | ||
| 35 | + public String toString() { | ||
| 36 | + return String.valueOf(members.size()) + "-member cluster"; | ||
| 37 | + } | ||
| 28 | 38 | ||
| 29 | /** | 39 | /** |
| 30 | * Removes all cluster members. | 40 | * Removes all cluster members. |
| ... | @@ -32,4 +42,34 @@ class UiCluster extends UiElement { | ... | @@ -32,4 +42,34 @@ class UiCluster extends UiElement { |
| 32 | void clear() { | 42 | void clear() { |
| 33 | members.clear(); | 43 | members.clear(); |
| 34 | } | 44 | } |
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * Returns the cluster member with the given identifier, or null if no | ||
| 48 | + * such member exists. | ||
| 49 | + * | ||
| 50 | + * @param id identifier of member to find | ||
| 51 | + * @return corresponding member | ||
| 52 | + */ | ||
| 53 | + public UiClusterMember find(NodeId id) { | ||
| 54 | + return lookup.get(id); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * Adds the given member to the cluster. | ||
| 59 | + * | ||
| 60 | + * @param member member to add | ||
| 61 | + */ | ||
| 62 | + public void add(UiClusterMember member) { | ||
| 63 | + members.add(member); | ||
| 64 | + lookup.put(member.id(), member); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * Returns the number of members in the cluster. | ||
| 69 | + * | ||
| 70 | + * @return number of members | ||
| 71 | + */ | ||
| 72 | + public int size() { | ||
| 73 | + return members.size(); | ||
| 74 | + } | ||
| 35 | } | 75 | } | ... | ... |
| ... | @@ -16,8 +16,41 @@ | ... | @@ -16,8 +16,41 @@ |
| 16 | 16 | ||
| 17 | package org.onosproject.ui.model.topo; | 17 | package org.onosproject.ui.model.topo; |
| 18 | 18 | ||
| 19 | +import org.onosproject.cluster.ControllerNode; | ||
| 20 | +import org.onosproject.cluster.NodeId; | ||
| 21 | + | ||
| 19 | /** | 22 | /** |
| 20 | * Represents an individual member of the cluster (ONOS instance). | 23 | * Represents an individual member of the cluster (ONOS instance). |
| 21 | */ | 24 | */ |
| 22 | public class UiClusterMember extends UiElement { | 25 | public class UiClusterMember extends UiElement { |
| 26 | + | ||
| 27 | + private final ControllerNode cnode; | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * Constructs a cluster member, with a reference to the specified | ||
| 31 | + * controller node instance. | ||
| 32 | + * | ||
| 33 | + * @param cnode underlying controller node. | ||
| 34 | + */ | ||
| 35 | + public UiClusterMember(ControllerNode cnode) { | ||
| 36 | + this.cnode = cnode; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * Updates the information about this cluster member. | ||
| 41 | + * | ||
| 42 | + * @param cnode underlying controller node | ||
| 43 | + */ | ||
| 44 | + public void update(ControllerNode cnode) { | ||
| 45 | + // TODO: update our information cache appropriately | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * Returns the identity of the cluster member. | ||
| 50 | + * | ||
| 51 | + * @return member identifier | ||
| 52 | + */ | ||
| 53 | + public NodeId id() { | ||
| 54 | + return cnode.id(); | ||
| 55 | + } | ||
| 23 | } | 56 | } | ... | ... |
| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | 16 | ||
| 17 | package org.onosproject.ui.model.topo; | 17 | package org.onosproject.ui.model.topo; |
| 18 | 18 | ||
| 19 | +import org.onosproject.cluster.NodeId; | ||
| 19 | import org.slf4j.Logger; | 20 | import org.slf4j.Logger; |
| 20 | import org.slf4j.LoggerFactory; | 21 | import org.slf4j.LoggerFactory; |
| 21 | 22 | ||
| ... | @@ -32,6 +33,11 @@ public class UiTopology extends UiElement { | ... | @@ -32,6 +33,11 @@ public class UiTopology extends UiElement { |
| 32 | private final UiCluster uiCluster = new UiCluster(); | 33 | private final UiCluster uiCluster = new UiCluster(); |
| 33 | private final Set<UiRegion> uiRegions = new TreeSet<>(); | 34 | private final Set<UiRegion> uiRegions = new TreeSet<>(); |
| 34 | 35 | ||
| 36 | + @Override | ||
| 37 | + public String toString() { | ||
| 38 | + return "Topology: " + uiCluster + ", " + uiRegions.size() + " regions"; | ||
| 39 | + } | ||
| 40 | + | ||
| 35 | /** | 41 | /** |
| 36 | * Clears the topology state; that is, drops all regions, devices, hosts, | 42 | * Clears the topology state; that is, drops all regions, devices, hosts, |
| 37 | * links, and cluster members. | 43 | * links, and cluster members. |
| ... | @@ -41,4 +47,42 @@ public class UiTopology extends UiElement { | ... | @@ -41,4 +47,42 @@ public class UiTopology extends UiElement { |
| 41 | uiRegions.clear(); | 47 | uiRegions.clear(); |
| 42 | uiCluster.clear(); | 48 | uiCluster.clear(); |
| 43 | } | 49 | } |
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Returns the cluster member with the given identifier, or null if no | ||
| 53 | + * such member. | ||
| 54 | + * | ||
| 55 | + * @param id cluster node identifier | ||
| 56 | + * @return the cluster member with that identifier | ||
| 57 | + */ | ||
| 58 | + public UiClusterMember findClusterMember(NodeId id) { | ||
| 59 | + return uiCluster.find(id); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * Adds the given cluster member to the topology model. | ||
| 64 | + * | ||
| 65 | + * @param member cluster member to add | ||
| 66 | + */ | ||
| 67 | + public void add(UiClusterMember member) { | ||
| 68 | + uiCluster.add(member); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Returns the number of members in the cluster. | ||
| 73 | + * | ||
| 74 | + * @return number of cluster members | ||
| 75 | + */ | ||
| 76 | + public int clusterMemberCount() { | ||
| 77 | + return uiCluster.size(); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + /** | ||
| 81 | + * Returns the number of regions configured in the topology. | ||
| 82 | + * | ||
| 83 | + * @return number of regions | ||
| 84 | + */ | ||
| 85 | + public int regionCount() { | ||
| 86 | + return uiRegions.size(); | ||
| 87 | + } | ||
| 44 | } | 88 | } | ... | ... |
| ... | @@ -24,6 +24,7 @@ import org.onosproject.net.DeviceId; | ... | @@ -24,6 +24,7 @@ import org.onosproject.net.DeviceId; |
| 24 | import org.onosproject.net.Host; | 24 | import org.onosproject.net.Host; |
| 25 | import org.onosproject.net.Link; | 25 | import org.onosproject.net.Link; |
| 26 | import org.onosproject.net.region.Region; | 26 | import org.onosproject.net.region.Region; |
| 27 | +import org.onosproject.ui.model.topo.UiClusterMember; | ||
| 27 | import org.onosproject.ui.model.topo.UiDevice; | 28 | import org.onosproject.ui.model.topo.UiDevice; |
| 28 | import org.onosproject.ui.model.topo.UiTopology; | 29 | import org.onosproject.ui.model.topo.UiTopology; |
| 29 | 30 | ||
| ... | @@ -42,6 +43,11 @@ class ModelCache { | ... | @@ -42,6 +43,11 @@ class ModelCache { |
| 42 | this.dispatcher = eventDispatcher; | 43 | this.dispatcher = eventDispatcher; |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 46 | + @Override | ||
| 47 | + public String toString() { | ||
| 48 | + return "ModelCache{" + uiTopology + "}"; | ||
| 49 | + } | ||
| 50 | + | ||
| 45 | /** | 51 | /** |
| 46 | * Clear our model. | 52 | * Clear our model. |
| 47 | */ | 53 | */ |
| ... | @@ -61,27 +67,21 @@ class ModelCache { | ... | @@ -61,27 +67,21 @@ class ModelCache { |
| 61 | } | 67 | } |
| 62 | 68 | ||
| 63 | 69 | ||
| 64 | - void addOrUpdateDevice(Device device) { | 70 | + /** |
| 65 | - // TODO: find or create device assoc. with parameter | 71 | + * Updates the model (adds a new instance if necessary) with the given |
| 66 | - // FIXME | 72 | + * controller node information. |
| 67 | - UiDevice uiDevice = new UiDevice(); | 73 | + * |
| 68 | - | 74 | + * @param cnode controller node to be added/updated |
| 69 | - // TODO: post the (correct) event | 75 | + */ |
| 70 | - dispatcher.post(new UiModelEvent(DEVICE_ADDED, uiDevice)); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - void removeDevice(Device device) { | ||
| 74 | - // TODO: get UiDevice associated with the given parameter; remove from model | ||
| 75 | - // FIXME | ||
| 76 | - UiDevice uiDevice = new UiDevice(); | ||
| 77 | - | ||
| 78 | - // TODO: post the (correct) event | ||
| 79 | - dispatcher.post(new UiModelEvent(DEVICE_REMOVED, uiDevice)); | ||
| 80 | - | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | void addOrUpdateClusterMember(ControllerNode cnode) { | 76 | void addOrUpdateClusterMember(ControllerNode cnode) { |
| 84 | - // TODO: find or create cluster member assoc. with parameter | 77 | + UiClusterMember member = uiTopology.findClusterMember(cnode.id()); |
| 78 | + if (member != null) { | ||
| 79 | + member.update(cnode); | ||
| 80 | + } else { | ||
| 81 | + member = new UiClusterMember(cnode); | ||
| 82 | + uiTopology.add(member); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | // TODO: post event | 85 | // TODO: post event |
| 86 | } | 86 | } |
| 87 | 87 | ||
| ... | @@ -90,7 +90,6 @@ class ModelCache { | ... | @@ -90,7 +90,6 @@ class ModelCache { |
| 90 | // TODO: post event | 90 | // TODO: post event |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | - | ||
| 94 | void updateMasterships(DeviceId deviceId, RoleInfo roleInfo) { | 93 | void updateMasterships(DeviceId deviceId, RoleInfo roleInfo) { |
| 95 | // TODO: store the updated mastership information | 94 | // TODO: store the updated mastership information |
| 96 | // TODO: post event | 95 | // TODO: post event |
| ... | @@ -106,6 +105,25 @@ class ModelCache { | ... | @@ -106,6 +105,25 @@ class ModelCache { |
| 106 | // TODO: post event | 105 | // TODO: post event |
| 107 | } | 106 | } |
| 108 | 107 | ||
| 108 | + void addOrUpdateDevice(Device device) { | ||
| 109 | + // TODO: find or create device assoc. with parameter | ||
| 110 | + // FIXME | ||
| 111 | + UiDevice uiDevice = new UiDevice(); | ||
| 112 | + | ||
| 113 | + // TODO: post the (correct) event | ||
| 114 | + dispatcher.post(new UiModelEvent(DEVICE_ADDED, uiDevice)); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + void removeDevice(Device device) { | ||
| 118 | + // TODO: get UiDevice associated with the given parameter; remove from model | ||
| 119 | + // FIXME | ||
| 120 | + UiDevice uiDevice = new UiDevice(); | ||
| 121 | + | ||
| 122 | + // TODO: post the (correct) event | ||
| 123 | + dispatcher.post(new UiModelEvent(DEVICE_REMOVED, uiDevice)); | ||
| 124 | + | ||
| 125 | + } | ||
| 126 | + | ||
| 109 | void addOrUpdateLink(Link link) { | 127 | void addOrUpdateLink(Link link) { |
| 110 | // TODO: find ui-link assoc. with parameter; create or update. | 128 | // TODO: find ui-link assoc. with parameter; create or update. |
| 111 | // TODO: post event | 129 | // TODO: post event |
| ... | @@ -129,4 +147,22 @@ class ModelCache { | ... | @@ -129,4 +147,22 @@ class ModelCache { |
| 129 | void removeHost(Host host) { | 147 | void removeHost(Host host) { |
| 130 | // TODO: find host assoc. with parameter; remove from model | 148 | // TODO: find host assoc. with parameter; remove from model |
| 131 | } | 149 | } |
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * Returns the number of members in the cluster. | ||
| 153 | + * | ||
| 154 | + * @return number of cluster members | ||
| 155 | + */ | ||
| 156 | + public int clusterMemberCount() { | ||
| 157 | + return uiTopology.clusterMemberCount(); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + /** | ||
| 161 | + * Returns the number of regions configured in the topology. | ||
| 162 | + * | ||
| 163 | + * @return number of regions | ||
| 164 | + */ | ||
| 165 | + public int regionCount() { | ||
| 166 | + return uiTopology.regionCount(); | ||
| 167 | + } | ||
| 132 | } | 168 | } | ... | ... |
| 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.model; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Base class for model test classes. | ||
| 21 | + */ | ||
| 22 | +public abstract class AbstractModelTest { | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * System agnostic end-of-line character. | ||
| 26 | + */ | ||
| 27 | + protected static final String EOL = String.format("%n"); | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * Prints the given string to stdout. | ||
| 31 | + * | ||
| 32 | + * @param s string to print | ||
| 33 | + */ | ||
| 34 | + protected void print(String s) { | ||
| 35 | + System.out.println(s); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * Prints the toString() of the given object to stdout. | ||
| 40 | + * | ||
| 41 | + * @param o object to print | ||
| 42 | + */ | ||
| 43 | + protected void print(Object o) { | ||
| 44 | + print(o.toString()); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * Prints the formatted string to stdout. | ||
| 49 | + * | ||
| 50 | + * @param fmt format string | ||
| 51 | + * @param params parameters | ||
| 52 | + * @see String#format(String, Object...) | ||
| 53 | + */ | ||
| 54 | + protected void print(String fmt, Object... params) { | ||
| 55 | + print(String.format(fmt, params)); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | +} |
| 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.model; | ||
| 18 | + | ||
| 19 | +import org.junit.Test; | ||
| 20 | +import org.onosproject.event.EventDispatcher; | ||
| 21 | + | ||
| 22 | +import static org.junit.Assert.assertEquals; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * Unit tests for {@link ModelCache}. | ||
| 26 | + */ | ||
| 27 | +public class ModelCacheTest extends AbstractModelTest { | ||
| 28 | + | ||
| 29 | + private static final EventDispatcher DISPATCHER = event -> { | ||
| 30 | + // Do we care? | ||
| 31 | + }; | ||
| 32 | + | ||
| 33 | + private ModelCache cache; | ||
| 34 | + | ||
| 35 | + @Test | ||
| 36 | + public void basic() { | ||
| 37 | + cache = new ModelCache(DISPATCHER); | ||
| 38 | + print(cache); | ||
| 39 | + assertEquals("unex # members", 0, cache.clusterMemberCount()); | ||
| 40 | + assertEquals("unex # regions", 0, cache.regionCount()); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | +} |
-
Please register or login to post a comment