| /* |
| * Copyright 2015-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.onosproject.ui.topo; |
| |
| import com.fasterxml.jackson.databind.JsonNode; |
| import com.fasterxml.jackson.databind.node.ArrayNode; |
| import com.fasterxml.jackson.databind.node.ObjectNode; |
| import org.onosproject.net.ConnectPoint; |
| import org.onosproject.net.Device; |
| import org.onosproject.net.Element; |
| import org.onosproject.net.Host; |
| import org.onosproject.net.Link; |
| import org.onosproject.net.device.DeviceService; |
| import org.onosproject.net.host.HostService; |
| import org.onosproject.net.link.LinkService; |
| import org.onosproject.ui.JsonUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import static com.google.common.base.Strings.isNullOrEmpty; |
| import static org.onosproject.net.ConnectPoint.deviceConnectPoint; |
| import static org.onosproject.net.DeviceId.deviceId; |
| import static org.onosproject.net.HostId.hostId; |
| |
| /** |
| * Encapsulates a selection of devices, hosts and links from the topology view. |
| */ |
| public class NodeSelection { |
| |
| private static final Logger log = |
| LoggerFactory.getLogger(NodeSelection.class); |
| |
| private static final String IDS = "ids"; |
| private static final String HOVER = "hover"; |
| private static final String LINK_ID_DELIM = "-"; |
| |
| private final DeviceService deviceService; |
| private final HostService hostService; |
| private final LinkService linkService; |
| |
| private final Set<String> ids; |
| private final String hover; |
| |
| private final Set<Device> devices = new HashSet<>(); |
| private final Set<Host> hosts = new HashSet<>(); |
| private final Set<Link> links = new HashSet<>(); |
| private Element hovered; |
| |
| /** |
| * Creates a node selection entity, from the given payload, using the |
| * supplied link, device and host services. Note that if a link, device |
| * or host was hovered over by the mouse, it is available |
| * via {@link #hovered()}. |
| * |
| * @param payload message payload |
| * @param deviceService device service |
| * @param hostService host service |
| * @param linkService link service |
| */ |
| public NodeSelection(ObjectNode payload, |
| DeviceService deviceService, |
| HostService hostService, |
| LinkService linkService) { |
| this.deviceService = deviceService; |
| this.hostService = hostService; |
| this.linkService = linkService; |
| |
| ids = extractIds(payload); |
| hover = extractHover(payload); |
| |
| // start by extracting the hovered element if any |
| if (isNullOrEmpty(hover)) { |
| hovered = null; |
| } else { |
| setHoveredElement(); |
| } |
| |
| // now go find the links, devices and hosts that are in the selection list |
| Set<String> unmatched = findLinks(ids); |
| unmatched = findDevices(unmatched); |
| unmatched = findHosts(unmatched); |
| if (!unmatched.isEmpty()) { |
| log.debug("Skipping unmatched IDs {}", unmatched); |
| } |
| |
| } |
| |
| /** |
| * Returns a view of the selected devices (hover not included). |
| * |
| * @return selected devices |
| */ |
| public Set<Device> devices() { |
| return Collections.unmodifiableSet(devices); |
| } |
| |
| /** |
| * Returns a view of the selected links (hover not included). |
| * |
| * @return selected links |
| */ |
| public Set<Link> links() { |
| return Collections.unmodifiableSet(links); |
| } |
| |
| /** |
| * Returns a view of the selected devices, including the hovered device |
| * if there was one. |
| * |
| * @return selected (plus hovered) devices |
| */ |
| public Set<Device> devicesWithHover() { |
| Set<Device> withHover; |
| if (hovered != null && hovered instanceof Device) { |
| withHover = new HashSet<>(devices); |
| withHover.add((Device) hovered); |
| } else { |
| withHover = devices; |
| } |
| return Collections.unmodifiableSet(withHover); |
| } |
| |
| /** |
| * Returns a view of the selected hosts (hover not included). |
| * |
| * @return selected hosts |
| */ |
| public Set<Host> hosts() { |
| return Collections.unmodifiableSet(hosts); |
| } |
| |
| /** |
| * Returns a view of the selected hosts, including the hovered host |
| * if thee was one. |
| * |
| * @return selected (plus hovered) hosts |
| */ |
| public Set<Host> hostsWithHover() { |
| Set<Host> withHover; |
| if (hovered != null && hovered instanceof Host) { |
| withHover = new HashSet<>(hosts); |
| withHover.add((Host) hovered); |
| } else { |
| withHover = hosts; |
| } |
| return Collections.unmodifiableSet(withHover); |
| } |
| |
| /** |
| * Returns a view of the selected links, including the hovered link |
| * if thee was one. |
| * |
| * @return selected (plus hovered) links |
| */ |
| public Set<Link> linksWithHover() { |
| Set<Link> withHover; |
| if (hovered != null && hovered instanceof Link) { |
| withHover = new HashSet<>(links); |
| withHover.add((Link) hovered); |
| } else { |
| withHover = links; |
| } |
| return Collections.unmodifiableSet(withHover); |
| } |
| |
| /** |
| * Returns the element (link, host or device) over which the mouse was hovering, |
| * or null. |
| * |
| * @return element hovered over |
| */ |
| public Element hovered() { |
| return hovered; |
| } |
| |
| /** |
| * Returns true if nothing is selected. |
| * |
| * @return true if nothing selected |
| */ |
| public boolean none() { |
| return devices().isEmpty() && hosts().isEmpty() && links().isEmpty(); |
| } |
| |
| @Override |
| public String toString() { |
| return "NodeSelection{" + |
| "ids=" + ids + |
| ", hover='" + hover + '\'' + |
| ", #devices=" + devices.size() + |
| ", #hosts=" + hosts.size() + |
| ", #links=" + links.size() + |
| '}'; |
| } |
| |
| // == helper methods |
| |
| private Set<String> extractIds(ObjectNode payload) { |
| ArrayNode array = (ArrayNode) payload.path(IDS); |
| if (array == null || array.size() == 0) { |
| return Collections.emptySet(); |
| } |
| |
| Set<String> ids = new HashSet<>(); |
| for (JsonNode node : array) { |
| ids.add(node.asText()); |
| } |
| return ids; |
| } |
| |
| private String extractHover(ObjectNode payload) { |
| return JsonUtils.string(payload, HOVER); |
| } |
| |
| private void setHoveredElement() { |
| Set<String> unmatched; |
| unmatched = new HashSet<>(); |
| unmatched.add(hover); |
| unmatched = findDevices(unmatched); |
| if (devices.size() == 1) { |
| hovered = devices.iterator().next(); |
| devices.clear(); |
| } else { |
| unmatched = findHosts(unmatched); |
| if (hosts.size() == 1) { |
| hovered = hosts.iterator().next(); |
| hosts.clear(); |
| } else { |
| hovered = null; |
| log.debug("Skipping unmatched HOVER {}", unmatched); |
| } |
| } |
| } |
| |
| private Set<String> findDevices(Set<String> ids) { |
| Set<String> unmatched = new HashSet<>(); |
| Device device; |
| |
| for (String id : ids) { |
| try { |
| device = deviceService.getDevice(deviceId(id)); |
| if (device != null) { |
| devices.add(device); |
| } else { |
| unmatched.add(id); |
| } |
| } catch (Exception e) { |
| unmatched.add(id); |
| } |
| } |
| return unmatched; |
| } |
| |
| private Set<String> findHosts(Set<String> ids) { |
| Set<String> unmatched = new HashSet<>(); |
| Host host; |
| |
| for (String id : ids) { |
| try { |
| host = hostService.getHost(hostId(id)); |
| if (host != null) { |
| hosts.add(host); |
| } else { |
| unmatched.add(id); |
| } |
| } catch (Exception e) { |
| unmatched.add(id); |
| } |
| } |
| return unmatched; |
| } |
| |
| private Set<String> findLinks(Set<String> ids) { |
| Set<String> unmatched = new HashSet<>(); |
| ConnectPoint cpSrc, cpDst; |
| Link link; |
| |
| for (String id : ids) { |
| try { |
| String[] connectPoints = id.split(LINK_ID_DELIM); |
| if (connectPoints.length != 2) { |
| unmatched.add(id); |
| continue; |
| } |
| |
| cpSrc = deviceConnectPoint(connectPoints[0]); |
| cpDst = deviceConnectPoint(connectPoints[1]); |
| link = linkService.getLink(cpSrc, cpDst); |
| |
| if (link != null) { |
| links.add(link); |
| } else { |
| unmatched.add(id); |
| } |
| |
| } catch (Exception e) { |
| unmatched.add(id); |
| } |
| } |
| return unmatched; |
| } |
| } |