blob: c7eba1eca70b17ed256cf082e42a21f5d4709a73 [file] [log] [blame]
Thomas Vachuskab4d3ff72015-12-01 09:53:51 -08001/*
2 * Copyright 2014,2015 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 */
16package org.onosproject.pathpainter;
17
18import com.fasterxml.jackson.databind.node.ObjectNode;
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableSet;
21import org.onlab.osgi.ServiceDirectory;
22import org.onosproject.net.DeviceId;
23import org.onosproject.net.ElementId;
24import org.onosproject.net.HostId;
25import org.onosproject.net.Link;
26import org.onosproject.net.Path;
27import org.onosproject.net.topology.PathService;
28import org.onosproject.ui.RequestHandler;
29import org.onosproject.ui.UiConnection;
30import org.onosproject.ui.UiMessageHandler;
31import org.onosproject.ui.topo.Highlights;
32import org.onosproject.ui.topo.TopoJson;
33import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
36import java.util.Collection;
37import java.util.List;
38import java.util.Set;
39
40/**
41 * Skeletal ONOS UI Topology-Overlay message handler.
42 */
43public class PathPainterTopovMessageHandler extends UiMessageHandler {
44
45 private static final String PAINTER_SET_SRC = "ppTopovSetSrc";
46 private static final String PAINTER_SET_DST = "ppTopovSetDst";
47 private static final String PAINTER_SWAP_SRC_DST = "ppTopovSwapSrcDst";
48 private static final String PAINTER_SET_MODE = "ppTopovSetMode";
49
50 private static final String PAINTER_NEXT_PATH = "ppTopovNextPath";
51 private static final String PAINTER_PREV_PATH = "ppTopovPrevPath";
52
53 private static final String ID = "id";
54 private static final String MODE = "mode";
55
56 private Set<Link> allPathLinks;
57
58 private enum Mode {
59 SHORTEST, DISJOINT, SRLG
60 }
61
62 private final Logger log = LoggerFactory.getLogger(getClass());
63
64 private PathService pathService;
65
66 private Mode currentMode = Mode.SHORTEST;
67 private ElementId src, dst;
68 private Mode mode = Mode.SHORTEST;
69 private List<Path> paths;
70 private int pathIndex;
71
72
73 // ===============-=-=-=-=-=-======================-=-=-=-=-=-=-================================
74
75
76 @Override
77 public void init(UiConnection connection, ServiceDirectory directory) {
78 super.init(connection, directory);
79 pathService = directory.get(PathService.class);
80 }
81
82 @Override
83 protected Collection<RequestHandler> createRequestHandlers() {
84 return ImmutableSet.of(
85 new SetSrcHandler(),
86 new SetDstHandler(),
87 new NextPathHandler(),
88 new PrevPathHandler()
89 );
90 }
91
92 // === -------------------------
93 // === Handler classes
94
95 private final class SetSrcHandler extends RequestHandler {
96 public SetSrcHandler() {
97 super(PAINTER_SET_SRC);
98 }
99
100 @Override
101 public void process(long sid, ObjectNode payload) {
102 String id = string(payload, ID);
103 src = elementId(id);
104 if (src.equals(dst)) {
105 dst = null;
106 }
107 findAndSendPaths();
108 }
109 }
110
111 private final class SetDstHandler extends RequestHandler {
112 public SetDstHandler() {
113 super(PAINTER_SET_DST);
114 }
115
116 @Override
117 public void process(long sid, ObjectNode payload) {
118 String id = string(payload, ID);
119 dst = elementId(id);
120 if (src.equals(dst)) {
121 src = null;
122 }
123 findAndSendPaths();
124 }
125 }
126
127 private final class NextPathHandler extends RequestHandler {
128 public NextPathHandler() {
129 super(PAINTER_NEXT_PATH);
130 }
131
132 @Override
133 public void process(long sid, ObjectNode payload) {
134 pathIndex = (pathIndex >= paths.size() - 1 ? 0 : pathIndex + 1);
135 hilightAndSendPaths();
136 }
137 }
138
139 private final class PrevPathHandler extends RequestHandler {
140 public PrevPathHandler() {
141 super(PAINTER_PREV_PATH);
142 }
143
144 @Override
145 public void process(long sid, ObjectNode payload) {
146 pathIndex = (pathIndex <= 0 ? paths.size() - 1 : pathIndex - 1);
147 hilightAndSendPaths();
148 }
149 }
150
151 // === ------------
152
153 private ElementId elementId(String id) {
154 try {
155 return DeviceId.deviceId(id);
156 } catch (IllegalArgumentException e) {
157 return HostId.hostId(id);
158 }
159 }
160
161 private void findAndSendPaths() {
162 log.info("src={}; dst={}; mode={}", src, dst, mode);
163 if (src != null && dst != null) {
164 paths = ImmutableList.copyOf(pathService.getPaths(src, dst));
165 pathIndex = 0;
166
167 ImmutableSet.Builder<Link> builder = ImmutableSet.builder();
168 paths.forEach(path -> path.links().forEach(builder::add));
169 allPathLinks = builder.build();
170 } else {
171 paths = ImmutableList.of();
172 allPathLinks = ImmutableSet.of();
173 }
174 hilightAndSendPaths();
175 }
176
177 private void hilightAndSendPaths() {
178 PathLinkMap linkMap = new PathLinkMap();
179 allPathLinks.forEach(linkMap::add);
180
181 // Prepare two working sets; one containing selected path links and
182 // the other containing all paths links.
183 Set<Link> selectedPathLinks = paths.isEmpty() ?
184 ImmutableSet.of() : ImmutableSet.copyOf(paths.get(pathIndex).links());
185
186 Highlights highlights = new Highlights();
187 for (PathLink plink : linkMap.biLinks()) {
188 plink.computeHilight(selectedPathLinks, allPathLinks);
189 highlights.add(plink.highlight(null));
190 }
191
192 sendMessage(TopoJson.highlightsMessage(highlights));
193 }
194
195 /*
196 private void addDeviceBadge(Highlights h, DeviceId devId, int n) {
197 DeviceHighlight dh = new DeviceHighlight(devId.toString());
198 dh.setBadge(createBadge(n));
199 h.add(dh);
200 }
201
202 private NodeBadge createBadge(int n) {
203 Status status = n > 3 ? Status.ERROR : Status.WARN;
204 String noun = n > 3 ? "(critical)" : "(problematic)";
205 String msg = "Egress links: " + n + " " + noun;
206 return NodeBadge.number(status, n, msg);
207 }
208 */
209
210}