-/*\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;
+ }
+ }
+}