blob: 7127ec1c932b3adc5bd4ba2c5d8e94e23a6fef6f [file] [log] [blame]
Simon Hunted804d52016-03-30 09:51:40 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Simon Hunted804d52016-03-30 09:51:40 -07003 *
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
Simon Huntf679c4e2016-04-01 17:02:24 -070017package org.onosproject.ui.impl.topo;
Simon Hunted804d52016-03-30 09:51:40 -070018
Simon Huntb1ce2602016-07-23 14:04:31 -070019import org.onosproject.net.region.RegionId;
Simon Huntf679c4e2016-04-01 17:02:24 -070020import org.onosproject.ui.UiTopoLayoutService;
21import org.onosproject.ui.impl.UiWebSocket;
Simon Huntcda9c032016-04-11 10:32:54 -070022import org.onosproject.ui.impl.topo.model.UiModelEvent;
23import org.onosproject.ui.impl.topo.model.UiModelListener;
Simon Huntf679c4e2016-04-01 17:02:24 -070024import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel;
Simon Huntd5b96732016-07-08 13:22:27 -070025import org.onosproject.ui.model.topo.UiClusterMember;
Simon Hunt98189192016-07-29 19:02:27 -070026import org.onosproject.ui.model.topo.UiNode;
Simon Huntd5b96732016-07-08 13:22:27 -070027import org.onosproject.ui.model.topo.UiRegion;
Simon Huntf679c4e2016-04-01 17:02:24 -070028import org.onosproject.ui.model.topo.UiTopoLayout;
Simon Hunted804d52016-03-30 09:51:40 -070029import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
Simon Huntb1ce2602016-07-23 14:04:31 -070032import java.util.HashSet;
Simon Huntd5b96732016-07-08 13:22:27 -070033import java.util.List;
Simon Hunt977aa052016-07-20 17:08:29 -070034import java.util.Set;
Simon Huntd5b96732016-07-08 13:22:27 -070035
Simon Hunted804d52016-03-30 09:51:40 -070036/**
Simon Huntf679c4e2016-04-01 17:02:24 -070037 * Coordinates with the {@link UiTopoLayoutService} to access
38 * {@link UiTopoLayout}s, and with the {@link UiSharedTopologyModel} which
Simon Huntcda9c032016-04-11 10:32:54 -070039 * maintains a local model of the network entities, tailored specifically
40 * for displaying on the UI.
Simon Hunted804d52016-03-30 09:51:40 -070041 * <p>
42 * Note that an instance of this class will be created for each
Simon Huntf679c4e2016-04-01 17:02:24 -070043 * {@link UiWebSocket} connection, and will contain
Simon Hunted804d52016-03-30 09:51:40 -070044 * the state of how the topology is laid out for the logged-in user.
Simon Huntd5b96732016-07-08 13:22:27 -070045 * <p>
46 * The expected pattern is for the {@link Topo2ViewMessageHandler} to obtain
47 * a reference to the session instance (via the {@link UiWebSocket}), and
48 * interact with it when topo-related events come in from the client.
Simon Hunted804d52016-03-30 09:51:40 -070049 */
Simon Huntcda9c032016-04-11 10:32:54 -070050public class UiTopoSession implements UiModelListener {
Simon Hunt977aa052016-07-20 17:08:29 -070051
Simon Hunted804d52016-03-30 09:51:40 -070052 private final Logger log = LoggerFactory.getLogger(getClass());
53
Simon Huntf679c4e2016-04-01 17:02:24 -070054 private final UiWebSocket webSocket;
Simon Hunt7092cc42016-04-06 18:40:17 -070055 private final String username;
56
57 final UiSharedTopologyModel sharedModel;
Simon Hunted804d52016-03-30 09:51:40 -070058
59 private boolean registered = false;
60
Thomas Vachuska92b016b2016-05-20 11:37:57 -070061 private UiTopoLayoutService layoutService;
Simon Hunt7092cc42016-04-06 18:40:17 -070062 private UiTopoLayout currentLayout;
Thomas Vachuska92b016b2016-05-20 11:37:57 -070063 private boolean messagesEnabled;
Simon Huntf679c4e2016-04-01 17:02:24 -070064
Simon Hunted804d52016-03-30 09:51:40 -070065 /**
Simon Hunt7092cc42016-04-06 18:40:17 -070066 * Creates a new topology session for the specified web socket connection.
67 *
Thomas Vachuska92b016b2016-05-20 11:37:57 -070068 * @param webSocket web socket
69 * @param model share topology model
70 * @param layoutService topology layout service
Simon Hunted804d52016-03-30 09:51:40 -070071 */
Thomas Vachuska92b016b2016-05-20 11:37:57 -070072 public UiTopoSession(UiWebSocket webSocket,
73 UiSharedTopologyModel model,
74 UiTopoLayoutService layoutService) {
Simon Huntf679c4e2016-04-01 17:02:24 -070075 this.webSocket = webSocket;
Simon Hunt7092cc42016-04-06 18:40:17 -070076 this.username = webSocket.userName();
Simon Huntcda9c032016-04-11 10:32:54 -070077 this.sharedModel = model;
Thomas Vachuska92b016b2016-05-20 11:37:57 -070078 this.layoutService = layoutService;
Simon Hunted804d52016-03-30 09:51:40 -070079 }
80
Simon Hunt977aa052016-07-20 17:08:29 -070081 // constructs a neutered instance, for unit testing
82 UiTopoSession() {
83 webSocket = null;
84 username = null;
85 sharedModel = null;
86 }
87
Simon Hunted804d52016-03-30 09:51:40 -070088 /**
Simon Hunt7092cc42016-04-06 18:40:17 -070089 * Initializes the session; registering with the shared model.
Simon Hunted804d52016-03-30 09:51:40 -070090 */
91 public void init() {
92 if (!registered) {
Simon Hunt7092cc42016-04-06 18:40:17 -070093 log.debug("{} : Registering with shared model", this);
Simon Hunted804d52016-03-30 09:51:40 -070094 sharedModel.register(this);
Thomas Vachuska92b016b2016-05-20 11:37:57 -070095 currentLayout = layoutService.getRootLayout();
Simon Hunted804d52016-03-30 09:51:40 -070096 registered = true;
97 } else {
98 log.warn("already registered");
99 }
100 }
101
102 /**
Simon Hunt7092cc42016-04-06 18:40:17 -0700103 * Destroys the session; unregistering from the shared model.
Simon Hunted804d52016-03-30 09:51:40 -0700104 */
105 public void destroy() {
Simon Hunt7092cc42016-04-06 18:40:17 -0700106 if (registered) {
107 log.debug("{} : Unregistering from shared model", this);
Simon Hunted804d52016-03-30 09:51:40 -0700108 sharedModel.unregister(this);
Simon Huntf679c4e2016-04-01 17:02:24 -0700109 registered = false;
Simon Hunted804d52016-03-30 09:51:40 -0700110 } else {
111 log.warn("already unregistered");
112 }
113 }
114
115 @Override
116 public String toString() {
Simon Huntf679c4e2016-04-01 17:02:24 -0700117 return String.format("{UiTopoSession for user <%s>}", username);
Simon Hunted804d52016-03-30 09:51:40 -0700118 }
Simon Huntcda9c032016-04-11 10:32:54 -0700119
120 @Override
121 public void event(UiModelEvent event) {
Yuta HIGUCHI28ad09a2016-06-28 17:08:29 -0700122 log.debug("Event received: {}", event);
Simon Huntcda9c032016-04-11 10:32:54 -0700123 // TODO: handle model events from the cache...
124 }
Thomas Vachuska92b016b2016-05-20 11:37:57 -0700125
126 /**
127 * Returns the current layout context.
128 *
129 * @return current topology layout
130 */
131 public UiTopoLayout currentLayout() {
132 return currentLayout;
133 }
134
135 /**
136 * Changes the current layout context to the specified layout.
137 *
138 * @param topoLayout new topology layout context
139 */
140 public void setCurrentLayout(UiTopoLayout topoLayout) {
141 currentLayout = topoLayout;
142 }
143
144 /**
145 * Enables or disables the transmission of topology event update messages.
146 *
147 * @param enabled true if messages should be sent
148 */
149 public void enableEvent(boolean enabled) {
150 messagesEnabled = enabled;
151 }
Simon Huntd5b96732016-07-08 13:22:27 -0700152
153 /**
154 * Returns the list of ONOS instances (cluster members).
155 *
156 * @return the list of ONOS instances
157 */
158 public List<UiClusterMember> getAllInstances() {
159 return sharedModel.getClusterMembers();
160 }
161
162 /**
163 * Returns the region for the specified layout.
164 *
165 * @param layout layout filter
166 * @return region that the layout is based upon
167 */
168 public UiRegion getRegion(UiTopoLayout layout) {
Simon Huntb1ce2602016-07-23 14:04:31 -0700169 RegionId rid = layout.regionId();
170 return rid == null ? sharedModel.getNullRegion() : sharedModel.getRegion(rid);
Simon Huntd5b96732016-07-08 13:22:27 -0700171 }
Simon Hunt977aa052016-07-20 17:08:29 -0700172
173 /**
Simon Hunt98189192016-07-29 19:02:27 -0700174 * Returns the regions/devices that are "peers" to this region. That is,
175 * based on the layout the user is viewing, all the regions/devices that
176 * are associated with layouts that share the same parent layout as this
177 * layout, AND that are linked to an element within this region.
Simon Hunt977aa052016-07-20 17:08:29 -0700178 *
179 * @param layout the layout being viewed
Simon Hunt98189192016-07-29 19:02:27 -0700180 * @return all regions/devices that are "siblings" to this layout's region
Simon Hunt977aa052016-07-20 17:08:29 -0700181 */
Simon Hunt98189192016-07-29 19:02:27 -0700182 public Set<UiNode> getPeerNodes(UiTopoLayout layout) {
183 Set<UiNode> peers = new HashSet<>();
184
185 // first, get the peer regions
186 Set<UiTopoLayout> peerLayouts = layoutService.getPeerLayouts(layout.id());
187 peerLayouts.forEach(l -> {
188 RegionId peerRegion = l.regionId();
189 peers.add(sharedModel.getRegion(peerRegion));
190 });
191
192 // now add the devices that reside in the parent region
193 if (!layout.isRoot()) {
194 UiTopoLayout parentLayout = layoutService.getLayout(layout.parent());
195 getRegion(parentLayout).devices().forEach(peers::add);
196 }
197
198 // TODO: Finally, filter out regions / devices that are not connected
199 // directly to this region by an implicit link
Simon Huntb1ce2602016-07-23 14:04:31 -0700200 return peers;
Simon Hunt977aa052016-07-20 17:08:29 -0700201 }
202
203 /**
204 * Returns the subregions of the region in the specified layout.
205 *
206 * @param layout the layout being viewed
207 * @return all regions that are "contained within" this layout's region
208 */
209 public Set<UiRegion> getSubRegions(UiTopoLayout layout) {
Simon Huntb1ce2602016-07-23 14:04:31 -0700210 Set<UiTopoLayout> kidLayouts = layoutService.getChildren(layout.id());
211 Set<UiRegion> kids = new HashSet<>();
212 kidLayouts.forEach(l -> kids.add(sharedModel.getRegion(l.regionId())));
213 return kids;
Simon Hunt977aa052016-07-20 17:08:29 -0700214 }
215
216 /**
Simon Huntb1ce2602016-07-23 14:04:31 -0700217 * Refreshes the model's internal state.
Simon Hunt977aa052016-07-20 17:08:29 -0700218 */
Simon Huntb1ce2602016-07-23 14:04:31 -0700219 public void refreshModel() {
220 sharedModel.refresh();
Simon Hunt977aa052016-07-20 17:08:29 -0700221 }
Simon Hunted804d52016-03-30 09:51:40 -0700222}