blob: ffc558daeb412d2df1e690e93a8decb3991340da [file] [log] [blame]
Thomas Vachuska3553b302015-03-07 14:49:43 -08001/*
2 * Copyright 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.ui.impl;
17
18import org.eclipse.jetty.websocket.WebSocket;
19import org.eclipse.jetty.websocket.WebSocketServlet;
20import org.onlab.osgi.DefaultServiceDirectory;
21import org.onlab.osgi.ServiceDirectory;
22
23import javax.servlet.ServletException;
24import javax.servlet.http.HttpServletRequest;
25import java.util.HashSet;
26import java.util.Iterator;
27import java.util.Set;
28import java.util.Timer;
29import java.util.TimerTask;
30
31/**
32 * Web socket servlet capable of creating web sockets for the user interface.
33 */
34public class UiWebSocketServlet extends WebSocketServlet {
35
36 private static final long PING_DELAY_MS = 5000;
37
Thomas Vachuska51f540f2015-05-27 17:26:57 -070038 private static UiWebSocketServlet instance;
39
Thomas Vachuska3553b302015-03-07 14:49:43 -080040 private ServiceDirectory directory = new DefaultServiceDirectory();
41
42 private final Set<UiWebSocket> sockets = new HashSet<>();
43 private final Timer timer = new Timer();
44 private final TimerTask pruner = new Pruner();
Thomas Vachuska4e0e0932015-07-24 10:14:34 -070045 private boolean isStopped = false;
Thomas Vachuska3553b302015-03-07 14:49:43 -080046
Thomas Vachuska51f540f2015-05-27 17:26:57 -070047 /**
48 * Closes all currently open UI web-sockets.
49 */
50 public static void closeAll() {
51 if (instance != null) {
Thomas Vachuska4e0e0932015-07-24 10:14:34 -070052 instance.isStopped = true;
Thomas Vachuska51f540f2015-05-27 17:26:57 -070053 instance.sockets.forEach(UiWebSocket::close);
54 instance.sockets.clear();
Thomas Vachuska4e0e0932015-07-24 10:14:34 -070055 instance.pruner.cancel();
56 instance.timer.cancel();
Thomas Vachuska51f540f2015-05-27 17:26:57 -070057 }
58 }
59
Thomas Vachuska3553b302015-03-07 14:49:43 -080060 @Override
61 public void init() throws ServletException {
62 super.init();
Thomas Vachuska51f540f2015-05-27 17:26:57 -070063 instance = this;
Thomas Vachuska3553b302015-03-07 14:49:43 -080064 timer.schedule(pruner, PING_DELAY_MS, PING_DELAY_MS);
65 }
66
67 @Override
68 public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
Thomas Vachuska4e0e0932015-07-24 10:14:34 -070069 if (isStopped) {
70 return null;
71 }
Thomas Vachuska3553b302015-03-07 14:49:43 -080072 UiWebSocket socket = new UiWebSocket(directory);
73 synchronized (sockets) {
74 sockets.add(socket);
75 }
76 return socket;
77 }
78
79 // Task for pruning web-sockets that are idle.
80 private class Pruner extends TimerTask {
81 @Override
82 public void run() {
83 synchronized (sockets) {
84 Iterator<UiWebSocket> it = sockets.iterator();
85 while (it.hasNext()) {
86 UiWebSocket socket = it.next();
87 if (socket.isIdle()) {
88 it.remove();
89 socket.close();
90 }
91 }
92 }
93 }
94 }
95}