Development of NETCONF RPCs for tr-069 adapter to
[oam/tr069-adapter.git] / netconf-server / src / main / java / org / commscope / tr069adapter / netconf / server / helper / ServerPortAllocationHelper.java
index 9e5479d..b292201 100644 (file)
-/*\r
- * ============LICENSE_START========================================================================\r
- * ONAP : tr-069-adapter\r
- * =================================================================================================\r
- * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
- * =================================================================================================\r
- * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
- * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
- * may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
- * either express or implied. See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- * ===============LICENSE_END=======================================================================\r
- */\r
-\r
-package org.commscope.tr069adapter.netconf.server.helper;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.PriorityQueue;\r
-import java.util.concurrent.Semaphore;\r
-\r
-import javax.annotation.PostConstruct;\r
-\r
-import org.commscope.tr069adapter.netconf.config.NetConfServerProperties;\r
-import org.commscope.tr069adapter.netconf.error.ServerPortAllocationException;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.springframework.beans.factory.annotation.Autowired;\r
-import org.springframework.stereotype.Component;\r
-\r
-@Component\r
-public class ServerPortAllocationHelper {\r
-\r
-  private static final Logger LOG = LoggerFactory.getLogger(ServerPortAllocationHelper.class);\r
-\r
-  private static Map<String, Semaphore> semaphoreMap = new HashMap<>();\r
-\r
-  private PriorityQueue<String> availablePorts = new PriorityQueue<>();\r
-\r
-  @Autowired\r
-  NetConfServerProperties config;\r
-\r
-  @PostConstruct\r
-  public void init() {\r
-    // read the port range and it the available ports.\r
-\r
-    Integer startPort = config.getDefaultNetconfStartPort();\r
-    Integer maxServers = config.getDefaultMaxServers();\r
-\r
-    try {\r
-      startPort = Integer.parseInt(config.getNetconfServersStartPort());\r
-    } catch (Exception e) {\r
-      LOG.warn(\r
-          "Failed to initialize the starting port from the environment {}. Hence using the default port range.",\r
-          config.getNetconfServersStartPort());\r
-    }\r
-\r
-    try {\r
-      maxServers = Integer.parseInt(config.getMaxNumOfNetconfServers());\r
-    } catch (Exception e) {\r
-      LOG.warn(\r
-          "Failed to initialize the max netconf server from the environment {} Hence using the default max servers.",\r
-          config.getMaxNumOfNetconfServers());\r
-    }\r
-\r
-    for (int i = startPort + maxServers - 1; i >= startPort; i--) {\r
-      semaphoreMap.put(String.valueOf(i), new Semaphore(1));\r
-      availablePorts.add(String.valueOf(i));\r
-    }\r
-    LOG.debug("Successfully populated available ports list.");\r
-  }\r
-  \r
-  public synchronized String reserveServerPort() throws ServerPortAllocationException {\r
-\r
-    if (availablePorts.isEmpty()) {\r
-      LOG.debug(\r
-          "All ports are exhausted. Hence cannot allocate a port to start new netconf server.");\r
-      return null;\r
-    }\r
-\r
-    String port = availablePorts.peek();\r
-\r
-    LOG.debug("Trying to reserve port : {}", port);\r
-    if (isServerPortInUse(port)) {\r
-      LOG.debug("Port {} is already in use.", port);\r
-      availablePorts.poll();\r
-      return reserveServerPort(); // retry if current port is not available\r
-    }\r
-\r
-    Semaphore semaphore = semaphoreMap.get(port);\r
-    boolean isAcquired = semaphore.tryAcquire();\r
-    if (isAcquired) {\r
-      LOG.debug("Failed to acquire a lock for port :{}. Hence retrying...", port);\r
-      return reserveServerPort();\r
-    }\r
-\r
-    availablePorts.poll();\r
-    semaphore.release();\r
-    LOG.debug("Rserved port is {}", port);\r
-    return port;\r
-  }\r
-\r
-  public boolean unReserveServerPort(String port) {\r
-\r
-    try {\r
-      Semaphore semaphore = semaphoreMap.get(port);\r
-      semaphore.acquire();\r
-      availablePorts.add(port);\r
-      semaphore.release();\r
-      LOG.error("Successfully un-reserved the port " + port + " to start netconf server.");\r
-    } catch (InterruptedException e) {\r
-      LOG.warn("Failed to un-reserve the port " + port, e);\r
-      Thread.currentThread().interrupt();\r
-      return false;\r
-    }\r
-\r
-    return true;\r
-  }\r
-\r
-  public boolean checkAndReserveServerPort(String port) {\r
-\r
-    try {\r
-      Semaphore semaphore = semaphoreMap.get(port);\r
-      semaphore.acquire();\r
-      if (isServerPortInUse(port)) {\r
-        LOG.error("Port {}  already in use.", port);\r
-        semaphore.release();\r
-        return false;\r
-      }\r
-      availablePorts.remove(port);\r
-      semaphore.release();\r
-      LOG.error("Successfully reserved the port {} to start netconf server", port);\r
-    } catch (InterruptedException e) {\r
-      Thread.currentThread().interrupt();\r
-      LOG.error("Failed to lock the port {} : Exception :{}", port, e.toString());\r
-      return checkAndReserveServerPort(port); // retry acquiring the lock.\r
-    }\r
-\r
-    return true;\r
-  }\r
-\r
-  public boolean isServerPortInUse(String port) {\r
-    return checkIfPortAvailable(port);\r
-  }\r
-\r
-  private static boolean checkIfPortAvailable(String portStr) {\r
-    Integer port = Integer.parseInt(portStr);\r
-    try (Socket ignored = new Socket("localhost", port)) {\r
-      return true;\r
-    } catch (IOException e) {\r
-      LOG.error("while checkIfPortAvailable {}", e.toString());\r
-      return false;\r
-    }\r
-  }\r
-}\r
+/*
+ * ============LICENSE_START========================================================================
+ * ONAP : tr-069-adapter
+ * =================================================================================================
+ * Copyright (C) 2020 CommScope Inc Intellectual Property.
+ * =================================================================================================
+ * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ===============LICENSE_END=======================================================================
+ */
+
+package org.commscope.tr069adapter.netconf.server.helper;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.concurrent.Semaphore;
+
+import javax.annotation.PostConstruct;
+
+import org.commscope.tr069adapter.netconf.config.NetConfServerProperties;
+import org.commscope.tr069adapter.netconf.error.ServerPortAllocationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ServerPortAllocationHelper {
+
+  private static final Logger LOG = LoggerFactory.getLogger(ServerPortAllocationHelper.class);
+
+  private static Map<String, Semaphore> semaphoreMap = new HashMap<>();
+
+  private PriorityQueue<String> availablePorts = new PriorityQueue<>();
+
+  @Autowired
+  NetConfServerProperties config;
+
+  @PostConstruct
+  public void init() {
+    // read the port range and it the available ports.
+
+    Integer startPort = config.getDefaultNetconfStartPort();
+    Integer maxServers = config.getDefaultMaxServers();
+
+    try {
+      startPort = Integer.parseInt(config.getNetconfServersStartPort());
+    } catch (Exception e) {
+      LOG.warn(
+          "Failed to initialize the starting port from the environment {}. Hence using the default port range.",
+          config.getNetconfServersStartPort());
+    }
+
+    try {
+      maxServers = Integer.parseInt(config.getMaxNumOfNetconfServers());
+    } catch (Exception e) {
+      LOG.warn(
+          "Failed to initialize the max netconf server from the environment {} Hence using the default max servers.",
+          config.getMaxNumOfNetconfServers());
+    }
+
+    for (int i = startPort + maxServers - 1; i >= startPort; i--) {
+      semaphoreMap.put(String.valueOf(i), new Semaphore(1));
+      availablePorts.add(String.valueOf(i));
+    }
+    LOG.debug("Successfully populated available ports list.");
+  }
+
+  public synchronized String reserveServerPort() throws ServerPortAllocationException {
+
+    if (availablePorts.isEmpty()) {
+      LOG.debug(
+          "All ports are exhausted. Hence cannot allocate a port to start new netconf server.");
+      return null;
+    }
+
+    String port = availablePorts.peek();
+
+    LOG.debug("Trying to reserve port : {}", port);
+    if (isServerPortInUse(port)) {
+      LOG.debug("Port {} is already in use.", port);
+      availablePorts.poll();
+      return reserveServerPort(); // retry if current port is not available
+    }
+
+    Semaphore semaphore = semaphoreMap.get(port);
+    boolean isAcquired = semaphore.tryAcquire();
+    if (isAcquired) {
+      LOG.debug("Failed to acquire a lock for port :{}. Hence retrying...", port);
+      return reserveServerPort();
+    }
+
+    availablePorts.poll();
+    semaphore.release();
+    LOG.debug("Rserved port is {}", port);
+    return port;
+  }
+
+  public boolean unReserveServerPort(String port) {
+
+    try {
+      Semaphore semaphore = semaphoreMap.get(port);
+      semaphore.acquire();
+      availablePorts.add(port);
+      semaphore.release();
+      LOG.error("Successfully un-reserved the port {} to start netconf server.", port);
+    } catch (InterruptedException e) {
+      LOG.warn("Failed to un-reserve the port  {} {}", port, e.getMessage());
+      Thread.currentThread().interrupt();
+      return false;
+    }
+
+    return true;
+  }
+
+  public boolean checkAndReserveServerPort(String port) {
+    port = port.replaceAll("[\n|\r|\t]", "_");
+    try {
+      Semaphore semaphore = semaphoreMap.get(port);
+      semaphore.acquire();
+      if (isServerPortInUse(port)) {
+        LOG.error("Port {}  already in use.", port);
+        semaphore.release();
+        return false;
+      }
+      availablePorts.remove(port);
+      semaphore.release();
+      LOG.error("Successfully reserved the port {} to start netconf server", port);
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+      LOG.error("Failed to lock the port {} : Exception :{}", port, e.toString());
+      return checkAndReserveServerPort(port); // retry acquiring the lock.
+    }
+
+    return true;
+  }
+
+  public boolean isServerPortInUse(String port) {
+    return checkIfPortAvailable(port);
+  }
+
+  private static boolean checkIfPortAvailable(String portStr) {
+    Integer port = Integer.parseInt(portStr);
+    try (Socket ignored = new Socket("localhost", port)) {
+      return true;
+    } catch (IOException e) {
+      LOG.error("while checkIfPortAvailable {}", e.toString());
+      return false;
+    }
+  }
+}