Bug 9256: Add websocket server config knob for ip 09/64109/2
authorTomas Cere <tcere@cisco.com>
Tue, 10 Oct 2017 08:50:57 +0000 (10:50 +0200)
committerTomas Cere <tcere@cisco.com>
Tue, 10 Oct 2017 08:54:40 +0000 (08:54 +0000)
Also cleans up a couple of ugly NPE catches.

Change-Id: Ifd164aa76c406cc2082d603df8732d636f6e06a1
Signed-off-by: Tomas Cere <tcere@cisco.com>
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfProviderImpl.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/streams/websockets/WebSocketServer.java
restconf/restconf-nb-bierman02/src/main/resources/org/opendaylight/blueprint/restconf-config.xml
restconf/sal-rest-connector-config/src/main/resources/initial/restconf.cfg

index 99200cb845f8d1c3aba750a9c7b9c8de5ed15653..818e76844e13d3dea86bb2ef92e88346335aa83a 100644 (file)
@@ -1241,17 +1241,13 @@ public class RestconfImpl implements RestconfService {
         }
 
         final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
-        int notificationPort = NOTIFICATION_PORT;
-        try {
-            final WebSocketServer webSocketServerInstance = WebSocketServer.getInstance();
-            notificationPort = webSocketServerInstance.getPort();
-        } catch (final NullPointerException e) {
-            WebSocketServer.createInstance(NOTIFICATION_PORT);
-        }
+
+        final WebSocketServer webSocketServerInstance = WebSocketServer.getInstance(NOTIFICATION_PORT);
+        final int notificationPort = webSocketServerInstance.getPort();
+
         final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme("ws");
-        final URI uriToWebsocketServer = uriToWebsocketServerBuilder.replacePath(streamName).build();
 
-        return uriToWebsocketServer;
+        return uriToWebsocketServerBuilder.replacePath(streamName).build();
     }
 
     /**
@@ -1301,17 +1297,13 @@ public class RestconfImpl implements RestconfService {
         this.broker.registerToListenDataChanges(datastore, scope, listener);
 
         final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
-        int notificationPort = NOTIFICATION_PORT;
-        try {
-            final WebSocketServer webSocketServerInstance = WebSocketServer.getInstance();
-            notificationPort = webSocketServerInstance.getPort();
-        } catch (final NullPointerException e) {
-            WebSocketServer.createInstance(NOTIFICATION_PORT);
-        }
+
+        final WebSocketServer webSocketServerInstance = WebSocketServer.getInstance(NOTIFICATION_PORT);
+        final int notificationPort = webSocketServerInstance.getPort();
+
         final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme("ws");
-        final URI uriToWebsocketServer = uriToWebsocketServerBuilder.replacePath(streamName).build();
 
-        return uriToWebsocketServer;
+        return uriToWebsocketServerBuilder.replacePath(streamName).build();
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
index 248863dca8ebf9d061e8844450ec47e6918546a5..614133bdd686ca38185c8aa2259743e3c0e8f23e 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.netconf.sal.restconf.impl.jmx.Put;
 import org.opendaylight.netconf.sal.restconf.impl.jmx.RestConnectorRuntimeMXBean;
 import org.opendaylight.netconf.sal.restconf.impl.jmx.Rpcs;
 import org.opendaylight.netconf.sal.streams.websockets.WebSocketServer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
@@ -36,6 +37,7 @@ public class RestconfProviderImpl extends AbstractMXBean
     private final DOMRpcService rpcService;
     private final DOMNotificationService notificationService;
     private final DOMMountPointService mountPointService;
+    private final IpAddress websocketAddress;
     private final PortNumber websocketPort;
     private final StatisticsRestconfServiceWrapper stats = StatisticsRestconfServiceWrapper.getInstance();
     private ListenerRegistration<SchemaContextListener> listenerRegistration;
@@ -43,13 +45,14 @@ public class RestconfProviderImpl extends AbstractMXBean
 
     public RestconfProviderImpl(DOMDataBroker domDataBroker, SchemaService schemaService, DOMRpcService rpcService,
             DOMNotificationService notificationService, DOMMountPointService mountPointService,
-            PortNumber websocketPort) {
+            IpAddress websocketAddress, PortNumber websocketPort) {
         super("Draft02ProviderStatistics", "restconf-connector", null);
         this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
         this.schemaService = Preconditions.checkNotNull(schemaService);
         this.rpcService = Preconditions.checkNotNull(rpcService);
         this.notificationService = Preconditions.checkNotNull(notificationService);
         this.mountPointService = Preconditions.checkNotNull(mountPointService);
+        this.websocketAddress = Preconditions.checkNotNull(websocketAddress);
         this.websocketPort = Preconditions.checkNotNull(websocketPort);
     }
 
@@ -63,7 +66,8 @@ public class RestconfProviderImpl extends AbstractMXBean
         ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext());
         ControllerContext.getInstance().setMountService(mountPointService);
 
-        this.webSocketServerThread = new Thread(WebSocketServer.createInstance(websocketPort.getValue().intValue()));
+        this.webSocketServerThread = new Thread(WebSocketServer.createInstance(
+                new String(websocketAddress.getValue()), websocketPort.getValue()));
         this.webSocketServerThread.setName("Web socket server on port " + websocketPort);
         this.webSocketServerThread.start();
 
index 23bff91a5317b47726ba8d8bf6f24bc380d33054..1fdfd4d63dae6c2dd5591720735c26437bf62c65 100644 (file)
@@ -26,15 +26,19 @@ public class WebSocketServer implements Runnable {
 
     private static final Logger LOG = LoggerFactory.getLogger(WebSocketServer.class);
 
+    private static final String DEFAULT_ADDRESS = "0.0.0.0";
+
     private static WebSocketServer instance = null;
 
+    private final String address;
     private final int port;
 
     private EventLoopGroup bossGroup;
     private EventLoopGroup workerGroup;
 
 
-    private WebSocketServer(final int port) {
+    private WebSocketServer(final String address, final int port) {
+        this.address = address;
         this.port = port;
     }
 
@@ -44,11 +48,17 @@ public class WebSocketServer implements Runnable {
      * @param port TCP port used for this server
      * @return instance of {@link WebSocketServer}
      */
-    public static WebSocketServer createInstance(final int port) {
+    private static WebSocketServer createInstance(final int port) {
+        instance = createInstance(DEFAULT_ADDRESS, port);
+        return instance;
+    }
+
+    public static WebSocketServer createInstance(final String address, final int port) {
         Preconditions.checkState(instance == null, "createInstance() has already been called");
+        Preconditions.checkNotNull(address, "Address cannot be null.");
         Preconditions.checkArgument(port >= 1024, "Privileged port (below 1024) is not allowed");
 
-        instance = new WebSocketServer(port);
+        instance = new WebSocketServer(address, port);
         return instance;
     }
 
@@ -71,6 +81,21 @@ public class WebSocketServer implements Runnable {
         return instance;
     }
 
+    /**
+     * Get instance of {@link WebSocketServer} created by {@link #createInstance(int)}.
+     * If an instance doesnt exist create one with the provided fallback port.
+     *
+     * @return instance of {@link WebSocketServer}
+     */
+    public static WebSocketServer getInstance(final int fallbackPort) {
+        if (instance != null) {
+            return instance;
+        }
+
+        LOG.warn("No instance for WebSocketServer found, creating one with a fallback port: {}", fallbackPort);
+        return createInstance(fallbackPort);
+    }
+
     /**
      * Destroy the existing instance.
      */
@@ -90,8 +115,8 @@ public class WebSocketServer implements Runnable {
             serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                     .childHandler(new WebSocketServerInitializer());
 
-            final Channel channel = serverBootstrap.bind(port).sync().channel();
-            LOG.info("Web socket server started at port {}.", port);
+            final Channel channel = serverBootstrap.bind(address, port).sync().channel();
+            LOG.info("Web socket server started at address {}, port {}.", address, port);
 
             channel.closeFuture().sync();
         } catch (final InterruptedException e) {
@@ -105,7 +130,7 @@ public class WebSocketServer implements Runnable {
      * Stops the web socket server and removes all listeners.
      */
     private void stop() {
-        LOG.debug("Stopping the web socket server instance on port {}", port);
+        LOG.info("Stopping the web socket server instance on port {}", port);
         Notificator.removeAllListeners();
         if (bossGroup != null) {
             bossGroup.shutdownGracefully();
index d3d249c6d44fe02fce37de3cc56b0c082dbf7a8a..676ab128e6359bb30c962336f87f88ed20373733 100644 (file)
@@ -16,6 +16,7 @@
 
   <cm:property-placeholder persistent-id="org.opendaylight.restconf" update-strategy="reload">
     <cm:default-properties>
+      <cm:property name="websocket-address" value="0.0.0.0"/>
       <cm:property name="websocket-port" value="8185"/>
     </cm:default-properties>
   </cm:property-placeholder>
     <argument value="${websocket-port}"/>
   </bean>
 
+  <bean id="webSocketAddress" class="org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress">
+    <argument value="${websocket-address}"/>
+  </bean>
+
   <bean id="restconfProviderDraft02" class="org.opendaylight.netconf.sal.restconf.impl.RestconfProviderImpl"
           init-method="start" destroy-method="close">
     <argument ref="domDataBroker"/>
@@ -54,6 +59,7 @@
     <argument ref="domRpcService"/>
     <argument ref="domNotificationService"/>
     <argument ref="domMountPointService"/>
+    <argument ref="webSocketAddress"/>
     <argument ref="webSocketPort"/>
   </bean>
 
index 088d9768245120e555e7ec30b810a39d4e99466e..4439da35f96c387088b61f21603de3e308be933a 100644 (file)
@@ -1,2 +1,3 @@
 # The port for the web socket server.
+#websocket-address=0.0.0.0
 #websocket-port=8185