--- /dev/null
+/*\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