blob: b87d0b7e4186cbd5e5ffe13866a15e160ba23132 [file] [log] [blame]
Simon Hunta17fa672015-08-19 18:42:22 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Simon Hunta17fa672015-08-19 18:42:22 -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.
Simon Hunta17fa672015-08-19 18:42:22 -070015 */
16
Simon Hunt191c84a2015-08-21 08:24:48 -070017package org.onosproject.ui.topo;
Simon Hunta17fa672015-08-19 18:42:22 -070018
19import com.fasterxml.jackson.databind.JsonNode;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.ObjectNode;
22import org.onosproject.net.Device;
Simon Hunt72297212015-08-25 10:15:33 -070023import org.onosproject.net.Element;
Simon Hunta17fa672015-08-19 18:42:22 -070024import org.onosproject.net.Host;
25import org.onosproject.net.device.DeviceService;
26import org.onosproject.net.host.HostService;
27import org.onosproject.ui.JsonUtils;
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
31import java.util.Collections;
32import java.util.HashSet;
33import java.util.Set;
34
35import static com.google.common.base.Strings.isNullOrEmpty;
36import static org.onosproject.net.DeviceId.deviceId;
37import static org.onosproject.net.HostId.hostId;
38
39/**
40 * Encapsulates a selection of devices and/or hosts from the topology view.
41 */
42public class NodeSelection {
43
Simon Hunt4fc86852015-08-20 17:57:52 -070044 private static final Logger log =
Simon Hunta17fa672015-08-19 18:42:22 -070045 LoggerFactory.getLogger(NodeSelection.class);
46
47 private static final String IDS = "ids";
48 private static final String HOVER = "hover";
49
50 private final DeviceService deviceService;
51 private final HostService hostService;
52
53 private final Set<String> ids;
54 private final String hover;
55
56 private final Set<Device> devices = new HashSet<>();
57 private final Set<Host> hosts = new HashSet<>();
Simon Hunt72297212015-08-25 10:15:33 -070058 private Element hovered;
Simon Hunta17fa672015-08-19 18:42:22 -070059
60 /**
61 * Creates a node selection entity, from the given payload, using the
Simon Hunt72297212015-08-25 10:15:33 -070062 * supplied device and host services. Note that if a device or host was
63 * hovered over by the mouse, it is available via {@link #hovered()}.
Simon Hunta17fa672015-08-19 18:42:22 -070064 *
65 * @param payload message payload
66 * @param deviceService device service
67 * @param hostService host service
68 */
69 public NodeSelection(ObjectNode payload,
70 DeviceService deviceService,
71 HostService hostService) {
72 this.deviceService = deviceService;
73 this.hostService = hostService;
74
75 ids = extractIds(payload);
76 hover = extractHover(payload);
77
Simon Hunt72297212015-08-25 10:15:33 -070078 // start by extracting the hovered element if any
79 if (isNullOrEmpty(hover)) {
80 hovered = null;
81 } else {
82 setHoveredElement();
83 }
84
85 // now go find the devices and hosts that are in the selection list
Simon Hunta17fa672015-08-19 18:42:22 -070086 Set<String> unmatched = findDevices(ids);
87 unmatched = findHosts(unmatched);
88 if (unmatched.size() > 0) {
89 log.debug("Skipping unmatched IDs {}", unmatched);
90 }
91
Simon Hunta17fa672015-08-19 18:42:22 -070092 }
93
94 /**
Simon Hunt72297212015-08-25 10:15:33 -070095 * Returns a view of the selected devices (hover not included).
Simon Hunta17fa672015-08-19 18:42:22 -070096 *
97 * @return selected devices
98 */
99 public Set<Device> devices() {
100 return Collections.unmodifiableSet(devices);
101 }
102
103 /**
Simon Hunt72297212015-08-25 10:15:33 -0700104 * Returns a view of the selected devices, including the hovered device
105 * if there was one.
106 *
107 * @return selected (plus hovered) devices
108 */
109 public Set<Device> devicesWithHover() {
110 Set<Device> withHover;
111 if (hovered != null && hovered instanceof Device) {
112 withHover = new HashSet<>(devices);
113 withHover.add((Device) hovered);
114 } else {
115 withHover = devices;
116 }
117 return Collections.unmodifiableSet(withHover);
118 }
119
120 /**
121 * Returns a view of the selected hosts (hover not included).
Simon Hunta17fa672015-08-19 18:42:22 -0700122 *
123 * @return selected hosts
124 */
125 public Set<Host> hosts() {
126 return Collections.unmodifiableSet(hosts);
127 }
128
129 /**
Simon Hunt72297212015-08-25 10:15:33 -0700130 * Returns a view of the selected hosts, including the hovered host
131 * if thee was one.
132 *
133 * @return selected (plus hovered) hosts
134 */
135 public Set<Host> hostsWithHover() {
136 Set<Host> withHover;
137 if (hovered != null && hovered instanceof Host) {
138 withHover = new HashSet<>(hosts);
139 withHover.add((Host) hovered);
140 } else {
141 withHover = hosts;
142 }
143 return Collections.unmodifiableSet(withHover);
144 }
145
146 /**
147 * Returns the element (host or device) over which the mouse was hovering,
148 * or null.
149 *
150 * @return element hovered over
151 */
152 public Element hovered() {
153 return hovered;
154 }
155
156 /**
Simon Hunta17fa672015-08-19 18:42:22 -0700157 * Returns true if nothing is selected.
158 *
159 * @return true if nothing selected
160 */
161 public boolean none() {
162 return devices().size() == 0 && hosts().size() == 0;
163 }
164
165 @Override
166 public String toString() {
167 return "NodeSelection{" +
168 "ids=" + ids +
169 ", hover='" + hover + '\'' +
170 ", #devices=" + devices.size() +
171 ", #hosts=" + hosts.size() +
172 '}';
173 }
174
175 // == helper methods
176
177 private Set<String> extractIds(ObjectNode payload) {
178 ArrayNode array = (ArrayNode) payload.path(IDS);
179 if (array == null || array.size() == 0) {
180 return Collections.emptySet();
181 }
182
183 Set<String> ids = new HashSet<>();
184 for (JsonNode node : array) {
185 ids.add(node.asText());
186 }
187 return ids;
188 }
189
190 private String extractHover(ObjectNode payload) {
191 return JsonUtils.string(payload, HOVER);
192 }
193
Simon Hunt72297212015-08-25 10:15:33 -0700194 private void setHoveredElement() {
195 Set<String> unmatched;
196 unmatched = new HashSet<>();
197 unmatched.add(hover);
198 unmatched = findDevices(unmatched);
199 if (devices.size() == 1) {
200 hovered = devices.iterator().next();
201 devices.clear();
202 } else {
203 unmatched = findHosts(unmatched);
204 if (hosts.size() == 1) {
205 hovered = hosts.iterator().next();
206 hosts.clear();
207 } else {
208 hovered = null;
209 log.debug("Skipping unmatched HOVER {}", unmatched);
210 }
211 }
212 }
213
Simon Hunta17fa672015-08-19 18:42:22 -0700214 private Set<String> findDevices(Set<String> ids) {
215 Set<String> unmatched = new HashSet<>();
216 Device device;
217
218 for (String id : ids) {
219 try {
220 device = deviceService.getDevice(deviceId(id));
221 if (device != null) {
222 devices.add(device);
223 } else {
Simon Hunt72297212015-08-25 10:15:33 -0700224 unmatched.add(id);
Simon Hunta17fa672015-08-19 18:42:22 -0700225 }
Simon Hunt72297212015-08-25 10:15:33 -0700226 } catch (Exception e) {
Simon Hunta17fa672015-08-19 18:42:22 -0700227 unmatched.add(id);
228 }
229 }
230 return unmatched;
231 }
232
233 private Set<String> findHosts(Set<String> ids) {
234 Set<String> unmatched = new HashSet<>();
235 Host host;
236
237 for (String id : ids) {
238 try {
239 host = hostService.getHost(hostId(id));
240 if (host != null) {
241 hosts.add(host);
242 } else {
Simon Hunt72297212015-08-25 10:15:33 -0700243 unmatched.add(id);
Simon Hunta17fa672015-08-19 18:42:22 -0700244 }
Simon Hunt72297212015-08-25 10:15:33 -0700245 } catch (Exception e) {
Simon Hunta17fa672015-08-19 18:42:22 -0700246 unmatched.add(id);
247 }
248 }
249 return unmatched;
250 }
Simon Hunta17fa672015-08-19 18:42:22 -0700251}