Development of NETCONF RPCs for tr-069 adapter to
[oam/tr069-adapter.git] / netconf-server / src / main / java / org / commscope / tr069adapter / netconf / server / NetConfServerManagerImpl.java
index 852d205..b1c7460 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;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ExecutorService;\r
-import java.util.concurrent.Executors;\r
-import org.apache.commons.io.FileUtils;\r
-import org.commscope.tr069adapter.acs.common.OperationDetails;\r
-import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
-import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
-import org.commscope.tr069adapter.common.deviceversion.DeviceVersionManager;\r
-import org.commscope.tr069adapter.common.deviceversion.ProfileDefinition;\r
-import org.commscope.tr069adapter.mapper.model.NetConfServerDetails;\r
-import org.commscope.tr069adapter.mapper.model.NetconfServerManagementError;\r
-import org.commscope.tr069adapter.mapper.model.VESNotification;\r
-import org.commscope.tr069adapter.mapper.model.VESNotificationResponse;\r
-import org.commscope.tr069adapter.netconf.config.NetConfServerProperties;\r
-import org.commscope.tr069adapter.netconf.dao.NetConfServerDetailsRepository;\r
-import org.commscope.tr069adapter.netconf.entity.NetConfServerDetailsEntity;\r
-import org.commscope.tr069adapter.netconf.error.RetryFailedException;\r
-import org.commscope.tr069adapter.netconf.error.ServerPortAllocationException;\r
-import org.commscope.tr069adapter.netconf.server.helper.ServerPortAllocationHelper;\r
-import org.commscope.tr069adapter.netconf.server.utils.NetConfServerConstants;\r
-import org.commscope.tr069adapter.netconf.server.ves.VESNotificationSender;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.springframework.beans.factory.annotation.Autowired;\r
-import org.springframework.http.HttpEntity;\r
-import org.springframework.http.HttpHeaders;\r
-import org.springframework.stereotype.Component;\r
-import org.springframework.web.client.RestTemplate;\r
-\r
-@Component\r
-public class NetConfServerManagerImpl {\r
-\r
-  private static final Logger LOG = LoggerFactory.getLogger(NetConfServerManagerImpl.class);\r
-\r
-  @Autowired\r
-  ServerPortAllocationHelper serverPortAllocator;\r
-\r
-  @Autowired\r
-  NetConfServerDetailsRepository netconfDAO;\r
-\r
-  @Autowired\r
-  NetConfServerProperties config;\r
-\r
-  @Autowired\r
-  NetconfServerStarter ncServerStarter;\r
-\r
-  @Autowired\r
-  RestartNetconfServerHandler restartServersHandler;\r
-\r
-  @Autowired\r
-  VESNotificationSender vesNotificationSender;\r
-\r
-  @Autowired\r
-  DeviceVersionManager versionManager;\r
-\r
-  ExecutorService executorService = Executors.newFixedThreadPool(10);\r
-\r
-  public boolean loadSchemas() {\r
-    LOG.debug("Loading yang schema started");\r
-    List<ProfileDefinition> profiles = versionManager.getSupportedProfileDefinitions();\r
-    try {\r
-      String commonSchemaPath = config.getSchemaDirPath() + "/common";\r
-\r
-      for (ProfileDefinition profile : profiles) {\r
-        String verSpecificSchemaPath =\r
-            config.getSchemaDirPath() + File.separator + profile.getNetConfSchemaPath();\r
-        File schemaDir = new File(commonSchemaPath);\r
-        File schemaVerDir = new File(verSpecificSchemaPath);\r
-\r
-        if (!schemaVerDir.isDirectory()) {\r
-          LOG.error("No folder path found for given version path {}",\r
-              schemaVerDir.getAbsolutePath());\r
-          return false;\r
-        }\r
-\r
-        try {\r
-          FileUtils.copyDirectory(schemaDir, schemaVerDir);\r
-        } catch (IOException e) {\r
-          LOG.error("Failed to copy directory " + e.getMessage());\r
-        }\r
-        boolean isSchemaLoaded = ncServerStarter.loadSchemas(schemaVerDir);\r
-        if (!isSchemaLoaded) {\r
-          LOG.debug("Failed to load schema for profile {}", profile.getProfileId());\r
-          return false;\r
-        }\r
-      }\r
-    } catch (Exception e) {\r
-      LOG.error("Load schema's failed in netconf server {}", e.getMessage());\r
-      return false;\r
-    }\r
-    LOG.debug("Loading yang schema completed");\r
-    return true;\r
-  }\r
-\r
-  public void restartServers() {\r
-    LOG.debug("Restarting all netconf servers during startup...");\r
-    Iterable<NetConfServerDetailsEntity> entities = netconfDAO.findAll();\r
-\r
-    for (NetConfServerDetailsEntity entity : entities) {\r
-      boolean isReserved = serverPortAllocator.checkAndReserveServerPort(entity.getListenPort());\r
-      if (isReserved) {\r
-        ServerStartTask task = new ServerStartTask(entity, this);\r
-        executorService.execute(task);\r
-      } else {\r
-        try {\r
-          restartServersHandler.restart(entity);\r
-        } catch (RetryFailedException e) {\r
-          LOG.error("submit task for restarting is failed {}", e.toString());\r
-        }\r
-      }\r
-    }\r
-    LOG.debug("Restarting netconf servers during startup is completed.");\r
-  }\r
-\r
-  public NetConfServerDetails createServer(String deviceId, String enodeBName, String swVersion,\r
-      String hwVersion) {\r
-    NetConfServerDetails result = new NetConfServerDetails();\r
-    NetConfServerDetailsEntity entity = null;\r
-    if (deviceId != null) {\r
-      entity = netconfDAO.findByDeviceId(deviceId);\r
-    } else if (enodeBName != null) {\r
-      entity = netconfDAO.findByEnodeBName(enodeBName);\r
-    } else {\r
-      // none is specified\r
-      LOG.error(\r
-          "Both deviceID and enodeBName are null. Hence failed to create the netconf server.");\r
-      return null;\r
-    }\r
-\r
-    if (null != entity && ncServerStarter.isNetConfServerRunning(deviceId)) {\r
-      if (isVersionChanged(entity, swVersion, hwVersion)) {\r
-        return restartOnVersionChange(deviceId, enodeBName, swVersion, hwVersion);\r
-      }\r
-\r
-      // found the entity. server is already running. double check and run\r
-      // if\r
-      // required. else return the details.\r
-\r
-      // update the ENB Name if Changed\r
-      entity.setEnodeBName(enodeBName);\r
-      netconfDAO.save(entity);\r
-      result = getNetConfServerDetails(deviceId, entity);\r
-      return result;\r
-    }\r
-\r
-    try {\r
-\r
-      String port = serverPortAllocator.reserveServerPort();\r
-      if (port == null) {\r
-        result.setError(NetconfServerManagementError.PORT_NOT_AVAILBLE);\r
-        LOG.error(\r
-            "All ports are exhausted. Hence cannot allocate a port to start new netconf server");\r
-        return result;\r
-      } else {\r
-        LOG.debug("Successfully reserved a port for deviceID={} ,port={}", deviceId, port);\r
-\r
-        // start the server\r
-        boolean isServerStarted = ncServerStarter.startServer(port, deviceId, swVersion, hwVersion);\r
-        boolean isPortInUse = serverPortAllocator.isServerPortInUse(port);\r
-\r
-        if (!isServerStarted || !isPortInUse) {\r
-          LOG.error(\r
-              "Failed to start netconf server for deviceID: {}, at port:{} , isServerStarted={} ,isPortInUse={}",\r
-              deviceId, port, isServerStarted, isPortInUse);\r
-          result.setError(NetconfServerManagementError.PORT_IN_USE);\r
-          return result;\r
-        }\r
-      }\r
-\r
-      // save the record in db\r
-      entity = new NetConfServerDetailsEntity();\r
-      entity.setDeviceId(deviceId);\r
-      entity.setListenPort(port);\r
-      entity.setEnodeBName(enodeBName);\r
-      entity.setSwVersion(swVersion);\r
-      entity.setHwVersion(hwVersion);\r
-      netconfDAO.save(entity);\r
-\r
-      result = getNetConfServerDetails(deviceId, entity);\r
-      LOG.debug("Successfully started netconf server for deviceID= {}, port={}", deviceId, port);\r
-\r
-    } catch (ServerPortAllocationException e) {\r
-      LOG.error("Failed to allocate a port {}", e.toString());\r
-    }\r
-\r
-    if (entity != null) {\r
-      result.setDeviceId(deviceId);\r
-      result.setListenPort(entity.getListenPort());\r
-      String netconfListenAddress = getServiceHost();\r
-      if (netconfListenAddress == null) {\r
-        netconfListenAddress = config.getNetconfServerIP();\r
-      }\r
-      result.setListenAddress(netconfListenAddress);\r
-      result.setError(NetconfServerManagementError.SUCCESS);\r
-    }\r
-    return result;\r
-  }\r
-\r
-  public NetConfServerDetails restartOnVersionChange(String deviceId, String enodeBName,\r
-      String swVersion, String hwVersion) {\r
-\r
-    NetConfServerDetailsEntity entity = null;\r
-    if (deviceId != null) {\r
-      entity = netconfDAO.findByDeviceId(deviceId);\r
-    }\r
-    if (entity == null) {\r
-      return null;\r
-    }\r
-\r
-    boolean isVersionChanged = isVersionChanged(entity, swVersion, hwVersion);\r
-    if (isVersionChanged) {\r
-      LOG.debug("software version changed, stopping the the existing netconf instance");\r
-      boolean result = this.ncServerStarter.stopServer(deviceId);\r
-      if (result) {\r
-        LOG.debug(\r
-            "successfully stopped the netconf instance; trying to start with new version yang models");\r
-        entity.setSwVersion(swVersion);\r
-        entity.setHwVersion(hwVersion);\r
-        netconfDAO.save(entity);\r
-\r
-        boolean isSuccess = startNetConfServerInstance(entity);\r
-\r
-        if (!isSuccess) {\r
-          try {\r
-            restartServersHandler.restart(entity);\r
-          } catch (RetryFailedException e) {\r
-            LOG.debug("");\r
-          }\r
-        }\r
-      }\r
-    }\r
-    return getNetConfServerDetails(deviceId, entity);\r
-  }\r
-\r
-\r
-  public boolean startNetConfServerInstance(NetConfServerDetailsEntity entity) {\r
-    boolean isSuccess = false;\r
-\r
-    boolean isServerStarted = ncServerStarter.startServer(entity.getListenPort(),\r
-        entity.getDeviceId(), entity.getSwVersion(), entity.getHwVersion());\r
-    if (isServerStarted) {\r
-      LOG.info("Successfully restarted NETCONF server {}  on port {} .",\r
-          entity.getDeviceId(), entity.getListenPort());\r
-      // we need to push the pnfEntry for IP updated\r
-      NetConfServerDetails details = getNetConfServerDetails(entity.getDeviceId(), entity);\r
-\r
-      final String baseUrl = config.getMapperPath() + "/registerNetconfServer";\r
-      URI uri = null;\r
-      try {\r
-        uri = new URI(baseUrl);\r
-      } catch (URISyntaxException e) {\r
-        LOG.error("error while contructing the URI {}", e.toString());\r
-      }\r
-      RestTemplate restTemplate = new RestTemplate();\r
-      HttpHeaders headers = new HttpHeaders();\r
-      HttpEntity<NetConfServerDetails> httpentity = new HttpEntity<>(details, headers);\r
-      if (uri != null) {\r
-        isSuccess = restTemplate.postForObject(uri, httpentity, Boolean.class);\r
-      }\r
-\r
-      if (!isSuccess) {\r
-        LOG.error("Netconf Register request is failed update the updated host details..");\r
-      } else {\r
-        LOG.debug("successfully started the server");\r
-      }\r
-    } else {\r
-      LOG.error("Failed to restart NETCONF server {}  on port {}  upon application startup.",\r
-          entity.getDeviceId(), entity.getListenPort());\r
-    }\r
-    return isSuccess;\r
-  }\r
-\r
-  private NetConfServerDetails getNetConfServerDetails(String deviceId,\r
-      NetConfServerDetailsEntity entity) {\r
-    NetConfServerDetails result = new NetConfServerDetails();\r
-    result.setDeviceId(deviceId);\r
-    result.setListenPort(entity.getListenPort());\r
-    result.setEnodeBName(entity.getEnodeBName());\r
-    result.setSwVersion(entity.getSwVersion());\r
-    result.setHwVersion(entity.getHwVersion());\r
-    String netconfListenAddress = getServiceHost();\r
-    if (netconfListenAddress == null) {\r
-      netconfListenAddress = config.getNetconfServerIP();\r
-    }\r
-    result.setListenAddress(netconfListenAddress);\r
-    result.setError(NetconfServerManagementError.SUCCESS);\r
-    return result;\r
-  }\r
-\r
-  public String unregister(String deviceId, String enodeBName) {\r
-    String resultMsg = null;\r
-    NetConfServerDetailsEntity entity = null;\r
-    if (deviceId != null) {\r
-      entity = this.netconfDAO.findByDeviceId(deviceId);\r
-    } else if (enodeBName != null) {\r
-      entity = this.netconfDAO.findByEnodeBName(enodeBName);\r
-    } else {\r
-      LOG.error(\r
-          "Both deviceID and enodeBName are null. Hence failed to unregister the netconf server.");\r
-      resultMsg = "Failed to unregister the device " + deviceId + ", enodeBName=" + enodeBName\r
-          + ". Invalid deviceId/enodeBName specified.";\r
-    }\r
-    if (entity == null) {\r
-      resultMsg = "Failed to unregister the device " + deviceId + ", enodeBName=" + enodeBName\r
-          + ". Invalid deviceId/enodeBName specified.";\r
-      LOG.info(resultMsg);\r
-      return resultMsg;\r
-    }\r
-    boolean result = this.ncServerStarter.stopServer(deviceId);\r
-    if (result) {\r
-      resultMsg =\r
-          "Successfully unregistered the device " + deviceId + " and enodeBName=" + enodeBName;\r
-      this.serverPortAllocator.unReserveServerPort(entity.getListenPort());\r
-      this.netconfDAO.delete(entity);\r
-      LOG.info(resultMsg);\r
-      delteHeartBeatTimer(deviceId);\r
-    } else {\r
-      resultMsg = "Failed to unregister the device " + deviceId + ", enodeBName=" + enodeBName;\r
-      LOG.error(resultMsg);\r
-    }\r
-\r
-    return resultMsg;\r
-  }\r
-\r
-  private void delteHeartBeatTimer(String deviceId) {\r
-    VESNotification vesNotification = new VESNotification();\r
-\r
-    vesNotification.seteNodeBName(deviceId);\r
-\r
-    ParameterDTO paramDTO = new ParameterDTO();\r
-    paramDTO.setParamName(NetConfServerConstants.HEART_BEAT);\r
-\r
-    List<ParameterDTO> paramDTOList = new ArrayList<>();\r
-    paramDTOList.add(paramDTO);\r
-\r
-    OperationDetails opDetails = new OperationDetails();\r
-    opDetails.setOpCode(TR069OperationCode.DELETE_OBJECT);\r
-    opDetails.setParmeters(paramDTOList);\r
-\r
-    vesNotification.setOperationDetails(opDetails);\r
-\r
-    VESNotificationResponse response =\r
-        vesNotificationSender.sendDeleteConfigNotification(vesNotification);\r
-\r
-    if (response.getStatusCode() == NetConfServerConstants.SUCCESS) {\r
-      LOG.info("Heart beat timer is deleted successfully for device {}", deviceId);\r
-    } else {\r
-      LOG.error("Failed to delete heart beat timer for device {}. ErrorMsg : {}", deviceId,\r
-          response.getResponseMsg());\r
-    }\r
-\r
-  }\r
-\r
-  public List<NetConfServerDetails> getServersInfo() {\r
-    Iterable<NetConfServerDetailsEntity> serverEntities = netconfDAO.findAll();\r
-    String netconfListenAddress = getServiceHost();\r
-    if (netconfListenAddress == null) {\r
-      netconfListenAddress = config.getNetconfServerIP();\r
-    }\r
-    List<NetConfServerDetails> result = new ArrayList<>();\r
-\r
-    for (NetConfServerDetailsEntity entity : serverEntities) {\r
-      NetConfServerDetails server = new NetConfServerDetails();\r
-      server.setDeviceId(entity.getDeviceId());\r
-      server.setEnodeBName(entity.getEnodeBName());\r
-      server.setError(NetconfServerManagementError.SUCCESS);\r
-      server.setListenAddress(netconfListenAddress);\r
-      server.setListenPort(entity.getListenPort());\r
-      server.setSwVersion(entity.getSwVersion());\r
-      server.setHwVersion(entity.getHwVersion());\r
-      result.add(server);\r
-    }\r
-    return result;\r
-  }\r
-\r
-  private String getServiceHost() {\r
-    Map<String, String> envs = System.getenv();\r
-    for (Entry<String, String> entry : envs.entrySet()) {\r
-      if (entry.getKey() != null && entry.getKey().endsWith("_NETCONF_SERVICE_SERVICE_HOST")) {\r
-        return entry.getValue();\r
-      }\r
-    }\r
-    return null;\r
-  }\r
-\r
-  private boolean isVersionChanged(NetConfServerDetailsEntity entity, String swVersion,\r
-      String hwVersion) {\r
-    String existingProfileId =\r
-        versionManager.getAssociatedProfileId(entity.getSwVersion(), entity.getHwVersion());\r
-    String newProfiled = versionManager.getAssociatedProfileId(swVersion, hwVersion);\r
-    return !existingProfileId.equalsIgnoreCase(newProfiled) ? true : false;\r
-  }\r
-\r
-  class ServerStartTask implements Runnable {\r
-\r
-    NetConfServerDetailsEntity entity;\r
-    NetConfServerManagerImpl netconfServerManager;\r
-\r
-    public ServerStartTask(NetConfServerDetailsEntity entity,\r
-        NetConfServerManagerImpl netconfServerManager) {\r
-      this.entity = entity;\r
-      this.netconfServerManager = netconfServerManager;\r
-    }\r
-\r
-    @Override\r
-    public void run() {\r
-      boolean isSuccess = netconfServerManager.startNetConfServerInstance(entity);\r
-      if (!isSuccess) {\r
-        try {\r
-          netconfServerManager.restartServersHandler.restart(entity);\r
-        } catch (RetryFailedException e) {\r
-          LOG.debug("");\r
-        }\r
-      }\r
-    }\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;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.apache.commons.io.FileUtils;
+import org.commscope.tr069adapter.acs.common.OperationDetails;
+import org.commscope.tr069adapter.acs.common.ParameterDTO;
+import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;
+import org.commscope.tr069adapter.common.deviceversion.DeviceVersionManager;
+import org.commscope.tr069adapter.common.deviceversion.ProfileDefinition;
+import org.commscope.tr069adapter.mapper.model.NetConfServerDetails;
+import org.commscope.tr069adapter.mapper.model.NetconfServerManagementError;
+import org.commscope.tr069adapter.mapper.model.VESNotification;
+import org.commscope.tr069adapter.mapper.model.VESNotificationResponse;
+import org.commscope.tr069adapter.netconf.config.NetConfServerProperties;
+import org.commscope.tr069adapter.netconf.dao.NetConfServerDetailsRepository;
+import org.commscope.tr069adapter.netconf.entity.NetConfServerDetailsEntity;
+import org.commscope.tr069adapter.netconf.error.RetryFailedException;
+import org.commscope.tr069adapter.netconf.error.ServerPortAllocationException;
+import org.commscope.tr069adapter.netconf.server.helper.ServerPortAllocationHelper;
+import org.commscope.tr069adapter.netconf.server.utils.NetConfServerConstants;
+import org.commscope.tr069adapter.netconf.server.ves.VESNotificationSender;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class NetConfServerManagerImpl {
+
+  private static final Logger LOG = LoggerFactory.getLogger(NetConfServerManagerImpl.class);
+
+  @Autowired
+  ServerPortAllocationHelper serverPortAllocator;
+
+  @Autowired
+  NetConfServerDetailsRepository netconfDAO;
+
+  @Autowired
+  NetConfServerProperties config;
+
+  @Autowired
+  NetconfServerStarter ncServerStarter;
+
+  @Autowired
+  RestartNetconfServerHandler restartServersHandler;
+
+  @Autowired
+  VESNotificationSender vesNotificationSender;
+
+  @Autowired
+  DeviceVersionManager versionManager;
+
+  ExecutorService executorService = Executors.newFixedThreadPool(10);
+
+  public boolean loadSchemas() {
+    LOG.debug("Loading yang schema started");
+    List<ProfileDefinition> profiles = versionManager.getSupportedProfileDefinitions();
+    try {
+      String commonSchemaPath = config.getSchemaDirPath() + "/common";
+
+      for (ProfileDefinition profile : profiles) {
+        String verSpecificSchemaPath =
+            config.getSchemaDirPath() + File.separator + profile.getNetConfSchemaPath();
+        File schemaDir = new File(commonSchemaPath);
+        File schemaVerDir = new File(verSpecificSchemaPath);
+
+        if (!schemaVerDir.isDirectory()) {
+          LOG.error("No folder path found for given version path {}",
+              schemaVerDir.getAbsolutePath());
+          return false;
+        }
+
+        try {
+          FileUtils.copyDirectory(schemaDir, schemaVerDir);
+        } catch (IOException e) {
+          LOG.error("Failed to copy directory {} ", e.getMessage());
+        }
+        boolean isSchemaLoaded = ncServerStarter.loadSchemas(schemaVerDir);
+        if (!isSchemaLoaded) {
+          LOG.debug("Failed to load schema for profile {}", profile.getProfileId());
+          return false;
+        }
+      }
+    } catch (Exception e) {
+      LOG.error("Load schemas failed in netconf server {}", e.getMessage());
+      return false;
+    }
+    LOG.debug("Loading yang schema completed");
+    return true;
+  }
+
+  public void restartServers() {
+    LOG.debug("Restarting all netconf servers during startup...");
+    Iterable<NetConfServerDetailsEntity> entities = netconfDAO.findAll();
+
+    for (NetConfServerDetailsEntity entity : entities) {
+      boolean isReserved = serverPortAllocator.checkAndReserveServerPort(entity.getListenPort());
+      if (isReserved) {
+        ServerStartTask task = new ServerStartTask(entity, this);
+        executorService.execute(task);
+      } else {
+        try {
+          restartServersHandler.restart(entity);
+        } catch (RetryFailedException e) {
+          LOG.error("Error while restarting netconf servers {}",e.getMessage());
+        }
+      }
+    }
+    LOG.debug("Restarting netconf servers during startup is completed.");
+  }
+
+  public NetConfServerDetails createServer(String deviceId, String enodeBName, String swVersion,
+      String hwVersion) {
+    NetConfServerDetails result = new NetConfServerDetails();
+    NetConfServerDetailsEntity entity = null;
+    if (deviceId != null) {
+      entity = netconfDAO.findByDeviceId(deviceId);
+    } else if (enodeBName != null) {
+      entity = netconfDAO.findByEnodeBName(enodeBName);
+    } else {
+      // none is specified
+      LOG.error(
+          "Both deviceID and enodeBName are null. Hence failed to create the netconf server.");
+      return null;
+    }
+
+    if (null != entity && ncServerStarter.isNetConfServerRunning(deviceId)) {
+      if (isVersionChanged(entity, swVersion, hwVersion)) {
+        return restartOnVersionChange(deviceId, enodeBName, swVersion, hwVersion);
+      }
+
+      // found the entity. server is already running. double check and run
+      // if
+      // required. else return the details.
+
+      // update the ENB Name if Changed
+      entity.setEnodeBName(enodeBName);
+      netconfDAO.save(entity);
+      result = getNetConfServerDetails(deviceId, entity);
+      return result;
+    }
+
+    try {
+
+      String port = serverPortAllocator.reserveServerPort();
+      if (port == null) {
+        result.setError(NetconfServerManagementError.PORT_NOT_AVAILBLE);
+        LOG.error(
+            "All ports are exhausted. Hence cannot allocate a port to start new netconf server");
+        return result;
+      } else {
+        LOG.debug("Successfully reserved a port for deviceID={} ,port={}", deviceId, port);
+
+        // start the server
+        boolean isServerStarted = ncServerStarter.startServer(port, deviceId, swVersion, hwVersion);
+        boolean isPortInUse = serverPortAllocator.isServerPortInUse(port);
+
+        if (!isServerStarted || !isPortInUse) {
+          LOG.error(
+              "Failed to start netconf server for deviceID: {}, at port:{} , isServerStarted={} ,isPortInUse={}",
+              deviceId, port, isServerStarted, isPortInUse);
+          result.setError(NetconfServerManagementError.PORT_IN_USE);
+          return result;
+        }
+      }
+
+      // save the record in db
+      entity = new NetConfServerDetailsEntity();
+      entity.setDeviceId(deviceId);
+      entity.setListenPort(port);
+      entity.setEnodeBName(enodeBName);
+      entity.setSwVersion(swVersion);
+      entity.setHwVersion(hwVersion);
+      netconfDAO.save(entity);
+
+      result = getNetConfServerDetails(deviceId, entity);
+      LOG.debug("Successfully started netconf server for deviceID= {}, port={}", deviceId, port);
+
+    } catch (ServerPortAllocationException e) {
+      LOG.error("Failed to allocate a port {}", e.toString());
+    }
+
+    if (entity != null) {
+      result.setDeviceId(deviceId);
+      result.setListenPort(entity.getListenPort());
+      String netconfListenAddress = getServiceHost();
+      if (netconfListenAddress == null) {
+        netconfListenAddress = config.getNetconfServerIP();
+      }
+      result.setListenAddress(netconfListenAddress);
+      result.setError(NetconfServerManagementError.SUCCESS);
+    }
+    return result;
+  }
+
+  public NetConfServerDetails restartOnVersionChange(String deviceId, String enodeBName,
+      String swVersion, String hwVersion) {
+
+    NetConfServerDetailsEntity entity = null;
+    if (deviceId != null) {
+      entity = netconfDAO.findByDeviceId(deviceId);
+    }
+    if (entity == null) {
+      return null;
+    }
+
+    boolean isVersionChanged = isVersionChanged(entity, swVersion, hwVersion);
+    if (isVersionChanged) {
+      LOG.debug("software version changed, stopping the the existing netconf instance");
+      boolean result = this.ncServerStarter.stopServer(deviceId);
+      if (result) {
+        LOG.debug(
+            "successfully stopped the netconf instance; trying to start with new version yang models");
+        entity.setSwVersion(swVersion);
+        entity.setHwVersion(hwVersion);
+        netconfDAO.save(entity);
+
+        boolean isSuccess = startNetConfServerInstance(entity);
+
+        if (!isSuccess) {
+          try {
+            restartServersHandler.restart(entity);
+          } catch (RetryFailedException e) {
+            LOG.debug("");
+          }
+        }
+      }
+    }
+    return getNetConfServerDetails(deviceId, entity);
+  }
+
+
+  public boolean startNetConfServerInstance(NetConfServerDetailsEntity entity) {
+    boolean isSuccess = false;
+
+    boolean isServerStarted = ncServerStarter.startServer(entity.getListenPort(),
+        entity.getDeviceId(), entity.getSwVersion(), entity.getHwVersion());
+    if (isServerStarted) {
+      LOG.info("Successfully restarted NETCONF server {}  on port {} .",
+          entity.getDeviceId(), entity.getListenPort());
+      // we need to push the pnfEntry for IP updated
+      NetConfServerDetails details = getNetConfServerDetails(entity.getDeviceId(), entity);
+
+      final String baseUrl = config.getMapperPath() + "/registerNetconfServer";
+      URI uri = null;
+      try {
+        uri = new URI(baseUrl);
+      } catch (URISyntaxException e) {
+        LOG.error("error while contructing the URI {}", e.toString());
+      }
+      RestTemplate restTemplate = new RestTemplate();
+      HttpHeaders headers = new HttpHeaders();
+      HttpEntity<NetConfServerDetails> httpentity = new HttpEntity<>(details, headers);
+      if (uri != null) {
+        isSuccess = restTemplate.postForObject(uri, httpentity, Boolean.class);
+      }
+
+      if (!isSuccess) {
+        LOG.error("Netconf Register request is failed update the updated host details..");
+      } else {
+        LOG.debug("successfully started the server");
+      }
+    } else {
+      LOG.error("Failed to restart NETCONF server {}  on port {}  upon application startup.",
+          entity.getDeviceId(), entity.getListenPort());
+    }
+    return isSuccess;
+  }
+
+  private NetConfServerDetails getNetConfServerDetails(String deviceId,
+      NetConfServerDetailsEntity entity) {
+    NetConfServerDetails result = new NetConfServerDetails();
+    result.setDeviceId(deviceId);
+    result.setListenPort(entity.getListenPort());
+    result.setEnodeBName(entity.getEnodeBName());
+    result.setSwVersion(entity.getSwVersion());
+    result.setHwVersion(entity.getHwVersion());
+    String netconfListenAddress = getServiceHost();
+    if (netconfListenAddress == null) {
+      netconfListenAddress = config.getNetconfServerIP();
+    }
+    result.setListenAddress(netconfListenAddress);
+    result.setError(NetconfServerManagementError.SUCCESS);
+    return result;
+  }
+
+  public String unregister(String deviceId, String enodeBName) {
+    String resultMsg = null;
+    NetConfServerDetailsEntity entity = null;
+    if (deviceId != null) {
+      entity = this.netconfDAO.findByDeviceId(deviceId);
+    } else if (enodeBName != null) {
+      entity = this.netconfDAO.findByEnodeBName(enodeBName);
+    } else {
+      LOG.error(
+          "Both deviceID and enodeBName are null. Hence failed to unregister the netconf server.");
+      resultMsg = "Failed to unregister the device " + deviceId + ", enodeBName=" + enodeBName
+          + ". Invalid deviceId/enodeBName specified.";
+    }
+    if (entity == null) {
+      resultMsg = "Failed to unregister the device " + deviceId + ", enodeBName=" + enodeBName
+          + ". Invalid deviceId/enodeBName specified.";
+      LOG.info(resultMsg);
+      return resultMsg;
+    }
+    boolean result = this.ncServerStarter.stopServer(deviceId);
+    if (result) {
+      resultMsg =
+          "Successfully unregistered the device " + deviceId + " and enodeBName=" + enodeBName;
+      this.serverPortAllocator.unReserveServerPort(entity.getListenPort());
+      this.netconfDAO.delete(entity);
+      LOG.info(resultMsg);
+      delteHeartBeatTimer(deviceId);
+    } else {
+      resultMsg = "Failed to unregister the device " + deviceId + ", enodeBName=" + enodeBName;
+      LOG.error(resultMsg);
+    }
+
+    return resultMsg;
+  }
+
+  private void delteHeartBeatTimer(String deviceId) {
+    VESNotification vesNotification = new VESNotification();
+
+    vesNotification.seteNodeBName(deviceId);
+
+    ParameterDTO paramDTO = new ParameterDTO();
+    paramDTO.setParamName(NetConfServerConstants.HEART_BEAT);
+
+    List<ParameterDTO> paramDTOList = new ArrayList<>();
+    paramDTOList.add(paramDTO);
+
+    OperationDetails opDetails = new OperationDetails();
+    opDetails.setOpCode(TR069OperationCode.DELETE_OBJECT);
+    opDetails.setParmeters(paramDTOList);
+
+    vesNotification.setOperationDetails(opDetails);
+
+    VESNotificationResponse response =
+        vesNotificationSender.sendDeleteConfigNotification(vesNotification);
+
+    if (response.getStatusCode() == NetConfServerConstants.SUCCESS) {
+      LOG.info("Heart beat timer is deleted successfully for device {}", deviceId);
+    } else {
+      LOG.error("Failed to delete heart beat timer for device {}. ErrorMsg : {}", deviceId,
+          response.getResponseMsg());
+    }
+
+  }
+
+  public List<NetConfServerDetails> getServersInfo() {
+    Iterable<NetConfServerDetailsEntity> serverEntities = netconfDAO.findAll();
+    String netconfListenAddress = getServiceHost();
+    if (netconfListenAddress == null) {
+      netconfListenAddress = config.getNetconfServerIP();
+    }
+    List<NetConfServerDetails> result = new ArrayList<>();
+
+    for (NetConfServerDetailsEntity entity : serverEntities) {
+      NetConfServerDetails server = new NetConfServerDetails();
+      server.setDeviceId(entity.getDeviceId());
+      server.setEnodeBName(entity.getEnodeBName());
+      server.setError(NetconfServerManagementError.SUCCESS);
+      server.setListenAddress(netconfListenAddress);
+      server.setListenPort(entity.getListenPort());
+      server.setSwVersion(entity.getSwVersion());
+      server.setHwVersion(entity.getHwVersion());
+      result.add(server);
+    }
+    return result;
+  }
+
+  private String getServiceHost() {
+    Map<String, String> envs = System.getenv();
+    for (Entry<String, String> entry : envs.entrySet()) {
+      if (entry.getKey() != null && entry.getKey().endsWith("_NETCONF_SERVICE_SERVICE_HOST")) {
+        return entry.getValue();
+      }
+    }
+    return null;
+  }
+
+  private boolean isVersionChanged(NetConfServerDetailsEntity entity, String swVersion,
+      String hwVersion) {
+    String existingProfileId =
+        versionManager.getAssociatedProfileId(entity.getSwVersion(), entity.getHwVersion());
+    String newProfiled = versionManager.getAssociatedProfileId(swVersion, hwVersion);
+    return !existingProfileId.equalsIgnoreCase(newProfiled) ? true : false;
+  }
+
+  class ServerStartTask implements Runnable {
+
+    NetConfServerDetailsEntity entity;
+    NetConfServerManagerImpl netconfServerManager;
+
+    public ServerStartTask(NetConfServerDetailsEntity entity,
+        NetConfServerManagerImpl netconfServerManager) {
+      this.entity = entity;
+      this.netconfServerManager = netconfServerManager;
+    }
+
+    @Override
+    public void run() {
+      boolean isSuccess = netconfServerManager.startNetConfServerInstance(entity);
+      if (!isSuccess) {
+        try {
+          netconfServerManager.restartServersHandler.restart(entity);
+        } catch (RetryFailedException e) {
+          LOG.debug("");
+        }
+      }
+    }
+
+  }
+}