Initial source code
[oam/tr069-adapter.git] / mapper / src / main / java / org / commscope / tr069adapter / mapper / acs / impl / PnPPreProvisioningHandler.java
diff --git a/mapper/src/main/java/org/commscope/tr069adapter/mapper/acs/impl/PnPPreProvisioningHandler.java b/mapper/src/main/java/org/commscope/tr069adapter/mapper/acs/impl/PnPPreProvisioningHandler.java
new file mode 100644 (file)
index 0000000..b6327ec
--- /dev/null
@@ -0,0 +1,320 @@
+/*\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.mapper.acs.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.commscope.tr069adapter.acs.common.DeviceInform;\r
+import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
+import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
+import org.commscope.tr069adapter.acs.common.OperationOptions;\r
+import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
+import org.commscope.tr069adapter.acs.common.dto.ConfigurationData;\r
+import org.commscope.tr069adapter.acs.common.dto.TR069DeviceDetails;\r
+import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
+import org.commscope.tr069adapter.acs.common.dto.TR069OperationDetails;\r
+import org.commscope.tr069adapter.acs.common.inform.BootInform;\r
+import org.commscope.tr069adapter.acs.common.inform.BootstrapInform;\r
+import org.commscope.tr069adapter.mapper.MOMetaData;\r
+import org.commscope.tr069adapter.mapper.MapperConfigProperties;\r
+import org.commscope.tr069adapter.mapper.sync.SynchronizedRequestHandler;\r
+import org.commscope.tr069adapter.mapper.util.MOMetaDataUtil;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.slf4j.MDC;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Component;\r
+import org.springframework.util.StringUtils;\r
+import org.springframework.web.client.RestTemplate;\r
+\r
+@Component\r
+public class PnPPreProvisioningHandler {\r
+\r
+  private static final Logger logger = LoggerFactory.getLogger(PnPPreProvisioningHandler.class);\r
+\r
+  private static String clientString = "client";\r
+  private static final String ADMIN_STATE = "AdminState";\r
+  private static final String ENODEB_NAME = "X_0005B9_eNBName";\r
+\r
+  @Autowired\r
+  SynchronizedRequestHandler syncHandler;\r
+\r
+  @Autowired\r
+  MOMetaDataUtil moMetaDataUtil;\r
+\r
+  @Autowired\r
+  MapperConfigProperties config;\r
+\r
+  private RestTemplate restTemplate = new RestTemplate();\r
+\r
+  /**\r
+   * @param notification\r
+   */\r
+  public void onDeviceNotification(DeviceInform notification) {\r
+    String deviceId = null;\r
+    try {\r
+      if (notification instanceof BootstrapInform || notification instanceof BootInform) {\r
+        logger.debug("Checking whether the PnP pre-configuration is enabled");\r
+        if (isPreConfigureOnPnPEnabled()) {\r
+          logger.info(\r
+              "Pre-configuration during Bootstrap or Boot is enabled, hence the configuration imported in Config DB shall be provisioned to the device");\r
+        } else {\r
+          logger.debug("Pre-configuration on PnP is disabled!!!");\r
+          return;\r
+        }\r
+      }\r
+\r
+      if (notification instanceof BootstrapInform) {\r
+        BootstrapInform bootstrapNotification = (BootstrapInform) notification;\r
+        deviceId = bootstrapNotification.getDeviceDetails().getDeviceId();\r
+        MDC.put(clientString, deviceId);\r
+        logger.info("Bootstrap notification received");\r
+        performPreProvisioning(deviceId, false);\r
+\r
+      } else if (notification instanceof BootInform) {\r
+        BootInform bootNotification = (BootInform) notification;\r
+        deviceId = bootNotification.getDeviceDetails().getDeviceId();\r
+        MDC.put(clientString, deviceId);\r
+        logger.info("Boot notification received");\r
+\r
+        performPreProvisioning(deviceId, true);\r
+      }\r
+\r
+      logger.debug("Successfully completed provisioning of PnP mandatory parameters");\r
+    } finally {\r
+      MDC.remove(clientString);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * @param deviceId\r
+   * @param isBoot\r
+   */\r
+  private void performPreProvisioning(String deviceId, boolean isBoot) {\r
+    List<DeviceRPCRequest> deviceRPCRequestList =\r
+        prepareNBIDeviceOperationrequest(deviceId, isBoot);\r
+    if (deviceRPCRequestList.isEmpty()) {\r
+      logger.debug("No Operation requests exists to perform pre provision on the device");\r
+      return;\r
+    }\r
+\r
+    boolean isMandatoryProvFailed = false;\r
+    for (DeviceRPCRequest deviceRPCRequest : deviceRPCRequestList) {\r
+      logger.info("Performing PROVISION operation");\r
+      DeviceRPCResponse deviceRPCResponse = syncHandler.performDeviceOperation(deviceRPCRequest);\r
+      logger.debug("Received Provisioning Operation result");\r
+      if (deviceRPCResponse == null || !StringUtils.isEmpty(deviceRPCResponse.getFaultString())) {\r
+        logger.error("Device operation failed, Reason: {}",\r
+            ((deviceRPCResponse == null) ? "Null Operation result"\r
+                : deviceRPCResponse.getFaultString()));\r
+        isMandatoryProvFailed = true;\r
+        break;\r
+      }\r
+\r
+      logger.debug("Provisioning is successful");\r
+    }\r
+\r
+    if (isMandatoryProvFailed) {\r
+      logger\r
+          .debug("Mandatory provisioning has failed, hence provisioning Admin down on the device");\r
+      provisionAdminDown(deviceRPCRequestList);\r
+      logger.debug("AdminDown Provisioning is successful");\r
+    }\r
+  }\r
+\r
+  private void provisionAdminDown(List<DeviceRPCRequest> deviceRPCRequestList) {\r
+    DeviceRPCRequest adminDownOpRequest = null;\r
+    for (DeviceRPCRequest nbiDeviceOperationRequest : deviceRPCRequestList) {\r
+      ParameterDTO param = nbiDeviceOperationRequest.getOpDetails().getParmeters().get(0);\r
+      if (param.getParamName().endsWith(ADMIN_STATE)) {\r
+        adminDownOpRequest = nbiDeviceOperationRequest;\r
+        break;\r
+      }\r
+    }\r
+    if (adminDownOpRequest != null) {\r
+      List<ParameterDTO> adminDownParams = adminDownOpRequest.getOpDetails().getParmeters();\r
+      for (ParameterDTO adminDownParam : adminDownParams) {\r
+        adminDownParam.setParamValue("0");\r
+      }\r
+      DeviceRPCResponse deviceRPCResponse = syncHandler.performDeviceOperation(adminDownOpRequest);\r
+      if (deviceRPCResponse == null || !StringUtils.isEmpty(deviceRPCResponse.getFaultString())) {\r
+        logger.error("Device operation failed, Reason: {}",\r
+            ((deviceRPCResponse == null) ? "Null Operation result"\r
+                : deviceRPCResponse.getFaultString()));\r
+      }\r
+    }\r
+  }\r
+\r
+  /**\r
+   * @param deviceId\r
+   * @param isBoot\r
+   * @return\r
+   */\r
+  private List<DeviceRPCRequest> prepareNBIDeviceOperationrequest(String deviceId, boolean isBoot) {\r
+    logger.debug("Preparing the NBI Device Operation Request");\r
+    List<DeviceRPCRequest> deviceRPCRequestList = new ArrayList<>();\r
+\r
+    ConfigurationData configData = getDeviceConfigurationData(deviceId);\r
+    if (configData == null || configData.getParameterMONameValueMap().isEmpty()) {\r
+      logger.debug("No configuration exists for the device");\r
+      return deviceRPCRequestList;\r
+    }\r
+\r
+    List<ParameterDTO> configParams = new ArrayList<>();\r
+    List<ParameterDTO> adminStateParams = new ArrayList<>();\r
+    Map<String, String> paramNameValueMap = configData.getParameterMONameValueMap();\r
+    Iterator<String> iter = paramNameValueMap.keySet().iterator();\r
+    while (iter.hasNext()) {\r
+      String paramName = iter.next();\r
+      String paramValue = paramNameValueMap.get(paramName);\r
+      MOMetaData moMetaData = moMetaDataUtil.getMetaDataByTR69Name(paramName);\r
+      if ((isBoot && !paramName.endsWith(ADMIN_STATE)) || moMetaData == null)\r
+        continue;\r
+      ParameterDTO parameterDTO = getParameterDTO(paramName, paramValue, moMetaData);\r
+\r
+      if (paramName.endsWith(ADMIN_STATE)) {\r
+        adminStateParams.add(parameterDTO);\r
+      } else {\r
+        configParams.add(parameterDTO);\r
+      }\r
+      logger.debug("Param -> {} Param Value: {}", paramName, paramValue);\r
+    }\r
+\r
+    if (configParams.isEmpty() && adminStateParams.isEmpty()) {\r
+      logger.debug("Empty parameters list from config db, hence not performing pre-provision");\r
+      return deviceRPCRequestList;\r
+    }\r
+\r
+    if (!configParams.isEmpty()) {\r
+      deviceRPCRequestList.add(createNBIOperationRequest(deviceId, configParams));\r
+    }\r
+\r
+    if (!adminStateParams.isEmpty()) {\r
+      deviceRPCRequestList.add(createNBIOperationRequest(deviceId, adminStateParams));\r
+    }\r
+\r
+    return deviceRPCRequestList;\r
+  }\r
+\r
+  private ParameterDTO getParameterDTO(String paramName, String paramValue, MOMetaData moMetaData) {\r
+    String dataType = moMetaData.getDataType();\r
+    if (dataType.equals("boolean")) {\r
+      if (paramValue.equalsIgnoreCase("true")) {\r
+        paramValue = "1";\r
+      } else if (paramValue.equalsIgnoreCase("false")) {\r
+        paramValue = "0";\r
+      }\r
+    }\r
+    ParameterDTO parameterDTO = new ParameterDTO(paramName, paramValue);\r
+    parameterDTO.setDataType(dataType);\r
+\r
+    return parameterDTO;\r
+  }\r
+\r
+  /**\r
+   * @param deviceId\r
+   * @param params\r
+   * @return\r
+   */\r
+  private DeviceRPCRequest createNBIOperationRequest(String deviceId, List<ParameterDTO> params) {\r
+    TR069OperationDetails opDetails = new TR069OperationDetails();\r
+    opDetails.setOpCode(TR069OperationCode.SET_PARAMETER_VALUES);\r
+    opDetails.setParmeters(params);\r
+\r
+    DeviceRPCRequest deviceRPCRequest = new DeviceRPCRequest();\r
+    TR069DeviceDetails tr069DeviceDetails = new TR069DeviceDetails();\r
+    tr069DeviceDetails.setDeviceId(deviceId);\r
+    deviceRPCRequest.setOpDetails(opDetails);\r
+    deviceRPCRequest.setDeviceDetails(tr069DeviceDetails);\r
+    OperationOptions options = new OperationOptions();\r
+    options.setExecutionTimeout(300l);\r
+    deviceRPCRequest.setOptions(options);\r
+\r
+    return deviceRPCRequest;\r
+  }\r
+\r
+  /**\r
+   * @param deviceId\r
+   * @return\r
+   */\r
+  private ConfigurationData getDeviceConfigurationData(String deviceId) {\r
+    String configDBURI = getConfigDBURI();\r
+    logger.debug("Device Configuration to be fetched from Config DB URI: {}", configDBURI);\r
+    ConfigurationData configData = null;\r
+    try {\r
+      configData = restTemplate.getForObject(configDBURI + deviceId, ConfigurationData.class);\r
+    } catch (Exception e) {\r
+      logger.error("An exception occurred to get the initial device configuration, Reason: {}",\r
+          e.getMessage());\r
+    }\r
+    return configData;\r
+  }\r
+\r
+  /**\r
+   * @return\r
+   */\r
+  private boolean isPreConfigureOnPnPEnabled() {\r
+    boolean isEnabled = false;\r
+    String preConfigureOnPnP = config.getPreConfigureOnPNP();\r
+    if (preConfigureOnPnP != null && ("true".equalsIgnoreCase(preConfigureOnPnP)\r
+        || "false".equalsIgnoreCase(preConfigureOnPnP))) {\r
+      isEnabled = Boolean.valueOf(preConfigureOnPnP);\r
+    }\r
+\r
+    return isEnabled;\r
+  }\r
+\r
+  /**\r
+   * @return\r
+   */\r
+  private String getConfigDBURI() {\r
+    return config.getConfigDBUri();\r
+\r
+  }\r
+\r
+  /**\r
+   * it will return the eNodBName if the configuration is imported\r
+   * \r
+   * @return String\r
+   */\r
+  public String getEnodeBName(String deviceId) {\r
+    String eNodeBName = null;\r
+    if (isPreConfigureOnPnPEnabled()) {\r
+      ConfigurationData configData = getDeviceConfigurationData(deviceId);\r
+      if (configData == null || configData.getParameterMONameValueMap().isEmpty()) {\r
+        logger.debug("No configuration exists for the device");\r
+        return eNodeBName;\r
+      }\r
+\r
+      Map<String, String> paramNameValueMap = configData.getParameterMONameValueMap();\r
+      Iterator<String> iter = paramNameValueMap.keySet().iterator();\r
+      while (iter.hasNext()) {\r
+        String paramName = iter.next();\r
+        if (paramName.endsWith(ENODEB_NAME)) {\r
+          eNodeBName = paramNameValueMap.get(paramName);\r
+          break;\r
+        }\r
+      }\r
+    }\r
+    return eNodeBName;\r
+  }\r
+}\r