BUG 2245 - Fixed Singular Field
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / UdpHandler.java
1 /*\r
2  * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 \r
9 package org.opendaylight.openflowjava.protocol.impl.core;\r
10 \r
11 import io.netty.bootstrap.Bootstrap;\r
12 import io.netty.channel.ChannelFuture;\r
13 import io.netty.channel.ChannelOption;\r
14 import io.netty.channel.EventLoopGroup;\r
15 import io.netty.channel.nio.NioEventLoopGroup;\r
16 import io.netty.channel.socket.nio.NioDatagramChannel;\r
17 import io.netty.util.concurrent.GenericFutureListener;\r
18 \r
19 import java.net.InetAddress;\r
20 import java.net.InetSocketAddress;\r
21 \r
22 import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration;\r
23 import org.opendaylight.openflowjava.protocol.impl.connection.ServerFacade;\r
24 import org.slf4j.Logger;\r
25 import org.slf4j.LoggerFactory;\r
26 \r
27 import com.google.common.util.concurrent.ListenableFuture;\r
28 import com.google.common.util.concurrent.SettableFuture;\r
29 \r
30 /**\r
31  * Class implementing server over UDP for handling incoming connections.\r
32  * \r
33  * @author michal.polkorab\r
34  */\r
35 public final class UdpHandler implements ServerFacade {\r
36 \r
37     private static final Logger LOGGER = LoggerFactory\r
38             .getLogger(UdpHandler.class);\r
39     private int port;\r
40     private EventLoopGroup group;\r
41     private final InetAddress startupAddress;\r
42     private final SettableFuture<Boolean> isOnlineFuture;\r
43     private UdpChannelInitializer channelInitializer;\r
44     private ThreadConfiguration threadConfig;\r
45 \r
46     /**\r
47      * Constructor of UdpHandler that listens on selected port.\r
48      *\r
49      * @param port listening port of UdpHandler server\r
50      */\r
51     public UdpHandler(final int port) {\r
52         this(null, port);\r
53     }\r
54 \r
55     /**\r
56      * Constructor of UdpHandler that listens on selected address and port.\r
57      * @param address listening address of UdpHandler server\r
58      * @param port listening port of UdpHandler server\r
59      */\r
60     public UdpHandler(final InetAddress address, final int port) {\r
61         this.port = port;\r
62         this.startupAddress = address;\r
63         isOnlineFuture = SettableFuture.create();\r
64     }\r
65 \r
66     @Override\r
67     public void run() {\r
68         if (threadConfig != null) {\r
69             group = new NioEventLoopGroup(threadConfig.getWorkerThreadCount());\r
70         } else {\r
71             group = new NioEventLoopGroup();\r
72         }\r
73         final ChannelFuture f;\r
74         try {\r
75             Bootstrap b = new Bootstrap();\r
76             b.group(group)\r
77              .channel(NioDatagramChannel.class)\r
78              .option(ChannelOption.SO_BROADCAST, false)\r
79              .handler(channelInitializer);\r
80 \r
81             if (startupAddress != null) {\r
82                 f = b.bind(startupAddress.getHostAddress(), port).sync();\r
83             } else {\r
84                 f = b.bind(port).sync();\r
85             }\r
86         } catch (InterruptedException e) {\r
87             LOGGER.error("Interrupted while binding port {}", port, e);\r
88             return;\r
89         }\r
90 \r
91         try {\r
92             InetSocketAddress isa = (InetSocketAddress) f.channel().localAddress();\r
93             String address = isa.getHostString();\r
94 \r
95             // Update port, as it may have been specified as 0\r
96             this.port = isa.getPort();\r
97 \r
98             LOGGER.debug("Address from udpHandler: {}", address);\r
99             isOnlineFuture.set(true);\r
100             LOGGER.info("Switch listener started and ready to accept incoming udp connections on port: {}", port);\r
101             f.channel().closeFuture().sync();\r
102         } catch (InterruptedException e) {\r
103             LOGGER.error("Interrupted while waiting for port {} shutdown", port, e);\r
104         } finally {\r
105             shutdown();\r
106         }\r
107     }\r
108 \r
109     @Override\r
110     public ListenableFuture<Boolean> shutdown() {\r
111         final SettableFuture<Boolean> result = SettableFuture.create();\r
112         group.shutdownGracefully().addListener(new GenericFutureListener<io.netty.util.concurrent.Future<Object>>() {\r
113 \r
114             @Override\r
115             public void operationComplete(\r
116                     final io.netty.util.concurrent.Future<Object> downResult) throws Exception {\r
117                 result.set(downResult.isSuccess());\r
118                 if (downResult.cause() != null) {\r
119                     result.setException(downResult.cause());\r
120                 }\r
121             }\r
122 \r
123         });\r
124         return result;\r
125     }\r
126 \r
127     @Override\r
128     public ListenableFuture<Boolean> getIsOnlineFuture() {\r
129         return isOnlineFuture;\r
130     }\r
131 \r
132     /**\r
133      * @return the port\r
134      */\r
135     public int getPort() {\r
136         return port;\r
137     }\r
138 \r
139     /**\r
140      * @param channelInitializer\r
141      */\r
142     public void setChannelInitializer(UdpChannelInitializer channelInitializer) {\r
143         this.channelInitializer = channelInitializer;\r
144     }\r
145 \r
146     @Override\r
147     public void setThreadConfig(ThreadConfiguration threadConfig) {\r
148         this.threadConfig = threadConfig;\r
149     }\r
150 }