blob: fe28186bae04381b191ede348bbccf1e4bf33f54 [file] [log] [blame]
Simon Hunt1ee09852015-09-29 12:28:14 -07001#set( $symbol_pound = '#' )
2#set( $symbol_dollar = '$' )
3#set( $symbol_escape = '\' )
4/*
5 * Copyright 2014,2015 Open Networking Laboratory
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package ${package};
20
21import com.fasterxml.jackson.databind.node.ObjectNode;
22import com.google.common.base.Strings;
23import com.google.common.collect.ImmutableSet;
24import org.onlab.osgi.ServiceDirectory;
25import org.onosproject.net.Device;
26import org.onosproject.net.DeviceId;
27import org.onosproject.net.Element;
28import org.onosproject.net.HostId;
29import org.onosproject.net.Link;
30import org.onosproject.net.device.DeviceService;
31import org.onosproject.net.host.HostService;
32import org.onosproject.net.link.LinkService;
33import org.onosproject.ui.RequestHandler;
34import org.onosproject.ui.UiConnection;
35import org.onosproject.ui.UiMessageHandler;
36import org.onosproject.ui.topo.Highlights;
37import org.onosproject.ui.topo.TopoJson;
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41import java.util.Collection;
42import java.util.HashSet;
43import java.util.Set;
44import java.util.Timer;
45import java.util.TimerTask;
46
47/**
48 * Skeletal ONOS UI Topology-Overlay message handler.
49 */
50public class AppUiTopovMessageHandler extends UiMessageHandler {
51
52 private static final String SAMPLE_DISPLAY_START = "sampleDisplayStart";
53 private static final String SAMPLE_DISPLAY_UPDATE = "sampleDisplayUpdate";
54 private static final String SAMPLE_DISPLAY_STOP = "sampleDisplayStop";
55
56 private static final String ID = "id";
57 private static final String MODE = "mode";
58
59 private static final long UPDATE_PERIOD_MS = 1000;
60
61 private static final Link[] EMPTY_LINK_SET = new Link[0];
62
63 private enum Mode { IDLE, MOUSE, LINK }
64
65 private final Logger log = LoggerFactory.getLogger(getClass());
66
67 private DeviceService deviceService;
68 private HostService hostService;
69 private LinkService linkService;
70
71 private final Timer timer = new Timer("sample-overlay");
72 private TimerTask demoTask = null;
73 private Mode currentMode = Mode.IDLE;
74 private Element elementOfNote;
75 private Link[] linkSet = EMPTY_LINK_SET;
76 private int linkIndex;
77
78
79 // ===============-=-=-=-=-=-======================-=-=-=-=-=-=-================================
80
81
82 @Override
83 public void init(UiConnection connection, ServiceDirectory directory) {
84 super.init(connection, directory);
85 deviceService = directory.get(DeviceService.class);
86 hostService = directory.get(HostService.class);
87 linkService = directory.get(LinkService.class);
88 }
89
90 @Override
91 protected Collection<RequestHandler> createRequestHandlers() {
92 return ImmutableSet.of(
93 new DisplayStartHandler(),
94 new DisplayUpdateHandler(),
95 new DisplayStopHandler()
96 );
97 }
98
99 // === -------------------------
100 // === Handler classes
101
102 private final class DisplayStartHandler extends RequestHandler {
103 public DisplayStartHandler() {
104 super(SAMPLE_DISPLAY_START);
105 }
106
107 @Override
108 public void process(long sid, ObjectNode payload) {
109 String mode = string(payload, MODE);
110
111 log.debug("Start Display: mode [{}]", mode);
112 clearState();
113 clearForMode();
114
115 switch (mode) {
116 case "mouse":
117 currentMode = Mode.MOUSE;
118 cancelTask();
119 sendMouseData();
120 break;
121
122 case "link":
123 currentMode = Mode.LINK;
124 scheduleTask();
125 initLinkSet();
126 sendLinkData();
127 break;
128
129 default:
130 currentMode = Mode.IDLE;
131 cancelTask();
132 break;
133 }
134 }
135 }
136
137 private final class DisplayUpdateHandler extends RequestHandler {
138 public DisplayUpdateHandler() {
139 super(SAMPLE_DISPLAY_UPDATE);
140 }
141
142 @Override
143 public void process(long sid, ObjectNode payload) {
144 String id = string(payload, ID);
145 log.debug("Update Display: id [{}]", id);
146 if (!Strings.isNullOrEmpty(id)) {
147 updateForMode(id);
148 } else {
149 clearForMode();
150 }
151 }
152 }
153
154 private final class DisplayStopHandler extends RequestHandler {
155 public DisplayStopHandler() {
156 super(SAMPLE_DISPLAY_STOP);
157 }
158
159 @Override
160 public void process(long sid, ObjectNode payload) {
161 log.debug("Stop Display");
162 cancelTask();
163 clearState();
164 clearForMode();
165 }
166 }
167
168 // === ------------
169
170 private void clearState() {
171 currentMode = Mode.IDLE;
172 elementOfNote = null;
173 linkSet = EMPTY_LINK_SET;
174 }
175
176 private void updateForMode(String id) {
177 log.debug("host service: {}", hostService);
178 log.debug("device service: {}", deviceService);
179
180 try {
181 HostId hid = HostId.hostId(id);
182 log.debug("host id {}", hid);
183 elementOfNote = hostService.getHost(hid);
184 log.debug("host element {}", elementOfNote);
185
186 } catch (Exception e) {
187 try {
188 DeviceId did = DeviceId.deviceId(id);
189 log.debug("device id {}", did);
190 elementOfNote = deviceService.getDevice(did);
191 log.debug("device element {}", elementOfNote);
192
193 } catch (Exception e2) {
194 log.debug("Unable to process ID [{}]", id);
195 elementOfNote = null;
196 }
197 }
198
199 switch (currentMode) {
200 case MOUSE:
201 sendMouseData();
202 break;
203
204 case LINK:
205 sendLinkData();
206 break;
207
208 default:
209 break;
210 }
211
212 }
213
214 private void clearForMode() {
215 sendHighlights(new Highlights());
216 }
217
218 private void sendHighlights(Highlights highlights) {
219 sendMessage(TopoJson.highlightsMessage(highlights));
220 }
221
222
223 private void sendMouseData() {
224 if (elementOfNote != null && elementOfNote instanceof Device) {
225 DeviceId devId = (DeviceId) elementOfNote.id();
226 Set<Link> links = linkService.getDeviceEgressLinks(devId);
227 sendHighlights(fromLinks(links, devId));
228 }
229 // Note: could also process Host, if available
230 }
231
232 private Highlights fromLinks(Set<Link> links, DeviceId devId) {
233 DemoLinkMap linkMap = new DemoLinkMap();
234 if (links != null) {
235 log.debug("Processing {} links", links.size());
236 links.forEach(linkMap::add);
237 } else {
238 log.debug("No egress links found for device {}", devId);
239 }
240
241 Highlights highlights = new Highlights();
242
243 for (DemoLink dlink : linkMap.biLinks()) {
244 dlink.makeImportant().setLabel("Yo!");
245 highlights.add(dlink.highlight(null));
246 }
247 return highlights;
248 }
249
250 private void initLinkSet() {
251 Set<Link> links = new HashSet<>();
252 for (Link link : linkService.getActiveLinks()) {
253 links.add(link);
254 }
255 linkSet = links.toArray(new Link[links.size()]);
256 linkIndex = 0;
257 log.debug("initialized link set to {}", linkSet.length);
258 }
259
260 private void sendLinkData() {
261 DemoLinkMap linkMap = new DemoLinkMap();
262 for (Link link : linkSet) {
263 linkMap.add(link);
264 }
265 DemoLink dl = linkMap.add(linkSet[linkIndex]);
266 dl.makeImportant().setLabel(Integer.toString(linkIndex));
267 log.debug("sending link data (index {})", linkIndex);
268
269 linkIndex += 1;
270 if (linkIndex >= linkSet.length) {
271 linkIndex = 0;
272 }
273
274 Highlights highlights = new Highlights();
275 for (DemoLink dlink : linkMap.biLinks()) {
276 highlights.add(dlink.highlight(null));
277 }
278
279 sendHighlights(highlights);
280 }
281
282 private synchronized void scheduleTask() {
283 if (demoTask == null) {
284 log.debug("Starting up demo task...");
285 demoTask = new DisplayUpdateTask();
286 timer.schedule(demoTask, UPDATE_PERIOD_MS, UPDATE_PERIOD_MS);
287 } else {
288 log.debug("(demo task already running");
289 }
290 }
291
292 private synchronized void cancelTask() {
293 if (demoTask != null) {
294 demoTask.cancel();
295 demoTask = null;
296 }
297 }
298
299
300 private class DisplayUpdateTask extends TimerTask {
301 @Override
302 public void run() {
303 try {
304 switch (currentMode) {
305 case LINK:
306 sendLinkData();
307 break;
308
309 default:
310 break;
311 }
312 } catch (Exception e) {
313 log.warn("Unable to process demo task: {}", e.getMessage());
314 log.debug("Oops", e);
315 }
316 }
317 }
318
319}