0a5f5f0ff03be26086ede6a78d3ba2dd156e812c
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / streams / websockets / WebSocketServer.java
1 package org.opendaylight.controller.sal.streams.websockets;
2
3 import com.google.common.base.Preconditions;
4 import io.netty.bootstrap.ServerBootstrap;
5 import io.netty.channel.Channel;
6 import io.netty.channel.EventLoopGroup;
7 import io.netty.channel.nio.NioEventLoopGroup;
8 import io.netty.channel.socket.nio.NioServerSocketChannel;
9 import org.opendaylight.controller.sal.streams.listeners.Notificator;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12
13 /**
14  * {@link WebSocketServer} is responsible to start and stop web socket server
15  */
16 public class WebSocketServer implements Runnable {
17
18     private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);
19     public static final int DEFAULT_PORT = 8181;
20     private EventLoopGroup bossGroup;
21     private EventLoopGroup workerGroup;
22     private static WebSocketServer instance = null;
23     private int port = DEFAULT_PORT;
24
25     private WebSocketServer(int port) {
26         this.port = port;
27     }
28
29     /**
30      * Create instance of {@link WebSocketServer}
31      *
32      * @param port
33      *            TCP port used for this server
34      * @return instance of {@link WebSocketServer}
35      */
36     public static WebSocketServer createInstance(int port) {
37         Preconditions.checkState(instance == null, "createInstance() has already been called");
38         Preconditions.checkArgument(port > 1024, "Privileged port (below 1024) is not allowed");
39
40         instance = new WebSocketServer(port);
41         return instance;
42     }
43
44     /**
45      * Return websocket TCP port
46      */
47     public int getPort() {
48         return port;
49     }
50
51     /**
52      * Get instance of {@link WebSocketServer} created by {@link #createInstance(int)}
53      *
54      * @return instance of {@link WebSocketServer}
55      */
56     public static WebSocketServer getInstance() {
57         Preconditions.checkNotNull(instance, "createInstance() must be called prior to getInstance()");
58         return instance;
59     }
60
61     /**
62      * Destroy this already created instance
63      */
64     public static void destroyInstance() {
65         Preconditions.checkState(instance != null, "createInstance() must be called prior to destroyInstance()");
66
67         instance.stop();
68         instance = null;
69     }
70
71     @Override
72     public void run() {
73         bossGroup = new NioEventLoopGroup();
74         workerGroup = new NioEventLoopGroup();
75         try {
76             ServerBootstrap b = new ServerBootstrap();
77             b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
78                     .childHandler(new WebSocketServerInitializer());
79
80             Channel ch = b.bind(port).sync().channel();
81             logger.info("Web socket server started at port {}.", port);
82
83             ch.closeFuture().sync();
84         } catch (InterruptedException e) {
85             // NOOP
86         } finally {
87             stop();
88         }
89     }
90
91     /**
92      * Stops the web socket server and removes all listeners.
93      */
94     private void stop() {
95         Notificator.removeAllListeners();
96         if (bossGroup != null) {
97             bossGroup.shutdownGracefully();
98             bossGroup = null;
99         }
100         if (workerGroup != null) {
101             workerGroup.shutdownGracefully();
102             workerGroup = null;
103         }
104     }
105
106 }