3858394dd90b716d012428e90fa04fae15223129
[oam/tr069-adapter.git] / mapper / src / main / java / org / commscope / tr069adapter / mapper / acs / impl / PnPPreProvisioningHandler.java
1 /*\r
2  * ============LICENSE_START========================================================================\r
3  * ONAP : tr-069-adapter\r
4  * =================================================================================================\r
5  * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
6  * =================================================================================================\r
7  * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
8  * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
9  * may obtain a copy of the License at\r
10  *\r
11  * http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
14  * either express or implied. See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  * ===============LICENSE_END=======================================================================\r
17  */\r
18 \r
19 package org.commscope.tr069adapter.mapper.acs.impl;\r
20 \r
21 import java.util.ArrayList;\r
22 import java.util.Iterator;\r
23 import java.util.List;\r
24 import java.util.Map;\r
25 import org.commscope.tr069adapter.acs.common.DeviceInform;\r
26 import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
27 import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
28 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
29 import org.commscope.tr069adapter.acs.common.dto.ConfigurationData;\r
30 import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
31 import org.commscope.tr069adapter.acs.common.dto.TR069OperationDetails;\r
32 import org.commscope.tr069adapter.acs.common.inform.BootInform;\r
33 import org.commscope.tr069adapter.acs.common.inform.BootstrapInform;\r
34 import org.commscope.tr069adapter.mapper.MOMetaData;\r
35 import org.commscope.tr069adapter.mapper.MapperConfigProperties;\r
36 import org.commscope.tr069adapter.mapper.sync.SynchronizedRequestHandler;\r
37 import org.commscope.tr069adapter.mapper.util.MOMetaDataUtil;\r
38 import org.commscope.tr069adapter.mapper.util.NetconfToTr069MapperUtil;\r
39 import org.slf4j.Logger;\r
40 import org.slf4j.LoggerFactory;\r
41 import org.slf4j.MDC;\r
42 import org.springframework.beans.factory.annotation.Autowired;\r
43 import org.springframework.http.HttpEntity;\r
44 import org.springframework.http.HttpHeaders;\r
45 import org.springframework.http.MediaType;\r
46 import org.springframework.http.ResponseEntity;\r
47 import org.springframework.stereotype.Component;\r
48 import org.springframework.util.LinkedMultiValueMap;\r
49 import org.springframework.util.MultiValueMap;\r
50 import org.springframework.util.StringUtils;\r
51 import org.springframework.web.client.RestTemplate;\r
52 \r
53 @Component\r
54 public class PnPPreProvisioningHandler {\r
55 \r
56   private static final Logger logger = LoggerFactory.getLogger(PnPPreProvisioningHandler.class);\r
57 \r
58   private static String clientString = "client";\r
59   private static final String ADMIN_STATE = "AdminState";\r
60   private static final String ENODEB_NAME = "X_0005B9_eNBName";\r
61 \r
62   @Autowired\r
63   SynchronizedRequestHandler syncHandler;\r
64 \r
65   @Autowired\r
66   MOMetaDataUtil moMetaDataUtil;\r
67 \r
68   @Autowired\r
69   MapperConfigProperties config;\r
70 \r
71   private RestTemplate restTemplate = new RestTemplate();\r
72 \r
73   /**\r
74    * @param notification\r
75    */\r
76   public void onDeviceNotification(DeviceInform notification) {\r
77     String deviceId = null;\r
78     try {\r
79       if (notification instanceof BootstrapInform || notification instanceof BootInform) {\r
80         logger.debug("Checking whether the PnP pre-configuration is enabled");\r
81         if (isPreConfigureOnPnPEnabled()) {\r
82           logger.info(\r
83               "Pre-configuration during Bootstrap or Boot is enabled, hence the configuration imported in Config DB shall be provisioned to the device");\r
84         } else {\r
85           logger.debug("Pre-configuration on PnP is disabled!!!");\r
86           return;\r
87         }\r
88       }\r
89 \r
90       if (notification instanceof BootstrapInform) {\r
91         BootstrapInform bootstrapNotification = (BootstrapInform) notification;\r
92         deviceId = bootstrapNotification.getDeviceDetails().getDeviceId();\r
93         MDC.put(clientString, deviceId);\r
94         logger.info("Bootstrap notification received");\r
95         performPreProvisioning(deviceId,\r
96             bootstrapNotification.getDeviceDetails().getSoftwareVersion(),\r
97             bootstrapNotification.getDeviceDetails().getHardwareVersion(), false);\r
98 \r
99       } else if (notification instanceof BootInform) {\r
100         BootInform bootNotification = (BootInform) notification;\r
101         deviceId = bootNotification.getDeviceDetails().getDeviceId();\r
102         MDC.put(clientString, deviceId);\r
103         logger.info("Boot notification received");\r
104 \r
105         performPreProvisioning(deviceId, bootNotification.getDeviceDetails().getSoftwareVersion(),\r
106             bootNotification.getDeviceDetails().getHardwareVersion(), true);\r
107       }\r
108 \r
109       logger.debug("Successfully completed provisioning of PnP mandatory parameters");\r
110     } finally {\r
111       MDC.remove(clientString);\r
112     }\r
113   }\r
114 \r
115   /**\r
116    * @param deviceId\r
117    * @param isBoot\r
118    */\r
119   private void performPreProvisioning(String deviceId, String swVersion, String hwVersion,\r
120       boolean isBoot) {\r
121     List<DeviceRPCRequest> deviceRPCRequestList =\r
122         prepareNBIDeviceOperationrequest(deviceId, swVersion, hwVersion, isBoot);\r
123     if (deviceRPCRequestList.isEmpty()) {\r
124       logger.debug("No Operation requests exists to perform pre provision on the device");\r
125       return;\r
126     }\r
127 \r
128     boolean isMandatoryProvFailed = false;\r
129     for (DeviceRPCRequest deviceRPCRequest : deviceRPCRequestList) {\r
130       logger.info("Performing PROVISION operation");\r
131       DeviceRPCResponse deviceRPCResponse = syncHandler.performDeviceOperation(deviceRPCRequest);\r
132       logger.debug("Received Provisioning Operation result");\r
133       if (deviceRPCResponse == null || !StringUtils.isEmpty(deviceRPCResponse.getFaultString())) {\r
134         logger.error("Device operation failed, Reason: {}", ((deviceRPCResponse == null)\r
135             ? "Null Operation result" : deviceRPCResponse.getFaultString()));\r
136         isMandatoryProvFailed = true;\r
137         break;\r
138       }\r
139 \r
140       logger.debug("Provisioning is successful");\r
141     }\r
142 \r
143     if (isMandatoryProvFailed) {\r
144       logger\r
145           .debug("Mandatory provisioning has failed, hence provisioning Admin down on the device");\r
146       provisionAdminDown(deviceRPCRequestList);\r
147       logger.debug("AdminDown Provisioning is successful");\r
148     }\r
149   }\r
150 \r
151   private void provisionAdminDown(List<DeviceRPCRequest> deviceRPCRequestList) {\r
152     DeviceRPCRequest adminDownOpRequest = null;\r
153     for (DeviceRPCRequest nbiDeviceOperationRequest : deviceRPCRequestList) {\r
154       ParameterDTO param = nbiDeviceOperationRequest.getOpDetails().getParmeters().get(0);\r
155       if (param.getParamName().endsWith(ADMIN_STATE)) {\r
156         adminDownOpRequest = nbiDeviceOperationRequest;\r
157         break;\r
158       }\r
159     }\r
160     if (adminDownOpRequest != null) {\r
161       List<ParameterDTO> adminDownParams = adminDownOpRequest.getOpDetails().getParmeters();\r
162       for (ParameterDTO adminDownParam : adminDownParams) {\r
163         adminDownParam.setParamValue("0");\r
164       }\r
165       DeviceRPCResponse deviceRPCResponse = syncHandler.performDeviceOperation(adminDownOpRequest);\r
166       if (deviceRPCResponse == null || !StringUtils.isEmpty(deviceRPCResponse.getFaultString())) {\r
167         logger.error("Device operation failed, Reason: {}", ((deviceRPCResponse == null)\r
168             ? "Null Operation result" : deviceRPCResponse.getFaultString()));\r
169       }\r
170     }\r
171   }\r
172 \r
173   /**\r
174    * @param deviceId\r
175    * @param isBoot\r
176    * @return\r
177    */\r
178   private List<DeviceRPCRequest> prepareNBIDeviceOperationrequest(String deviceId, String swVersion,\r
179       String hwVersion, boolean isBoot) {\r
180     logger.debug("Preparing the NBI Device Operation Request");\r
181     List<DeviceRPCRequest> deviceRPCRequestList = new ArrayList<>();\r
182 \r
183     ConfigurationData configData = getDeviceConfigurationData(deviceId, swVersion, hwVersion);\r
184     if (configData == null || configData.getParameterMONameValueMap().isEmpty()) {\r
185       logger.debug("No configuration exists for the device");\r
186       return deviceRPCRequestList;\r
187     }\r
188 \r
189     List<ParameterDTO> configParams = new ArrayList<>();\r
190     List<ParameterDTO> adminStateParams = new ArrayList<>();\r
191     Map<String, String> paramNameValueMap = configData.getParameterMONameValueMap();\r
192     Iterator<String> iter = paramNameValueMap.keySet().iterator();\r
193     while (iter.hasNext()) {\r
194       String paramName = iter.next();\r
195       String paramValue = paramNameValueMap.get(paramName);\r
196       MOMetaData moMetaData = moMetaDataUtil.getMetaDataByTR69Name(paramName, swVersion, hwVersion);\r
197       if ((isBoot && !paramName.endsWith(ADMIN_STATE)) || moMetaData == null)\r
198         continue;\r
199       ParameterDTO parameterDTO = getParameterDTO(paramName, paramValue, moMetaData);\r
200 \r
201       if (paramName.endsWith(ADMIN_STATE)) {\r
202         adminStateParams.add(parameterDTO);\r
203       } else {\r
204         configParams.add(parameterDTO);\r
205       }\r
206       logger.debug("Param -> {} Param Value: {}", paramName, paramValue);\r
207     }\r
208 \r
209     if (configParams.isEmpty() && adminStateParams.isEmpty()) {\r
210       logger.debug("Empty parameters list from config db, hence not performing pre-provision");\r
211       return deviceRPCRequestList;\r
212     }\r
213 \r
214     if (!configParams.isEmpty()) {\r
215       deviceRPCRequestList.add(createNBIOperationRequest(deviceId, configParams));\r
216     }\r
217 \r
218     if (!adminStateParams.isEmpty()) {\r
219       deviceRPCRequestList.add(createNBIOperationRequest(deviceId, adminStateParams));\r
220     }\r
221 \r
222     return deviceRPCRequestList;\r
223   }\r
224 \r
225   private ParameterDTO getParameterDTO(String paramName, String paramValue, MOMetaData moMetaData) {\r
226     String dataType = moMetaData.getDataType();\r
227     if (dataType.equals("boolean")) {\r
228       if (paramValue.equalsIgnoreCase("true")) {\r
229         paramValue = "1";\r
230       } else if (paramValue.equalsIgnoreCase("false")) {\r
231         paramValue = "0";\r
232       }\r
233     }\r
234     ParameterDTO parameterDTO = new ParameterDTO(paramName, paramValue);\r
235     parameterDTO.setDataType(dataType);\r
236 \r
237     return parameterDTO;\r
238   }\r
239 \r
240   /**\r
241    * @param deviceId\r
242    * @param params\r
243    * @return\r
244    */\r
245   private DeviceRPCRequest createNBIOperationRequest(String deviceId, List<ParameterDTO> params) {\r
246     TR069OperationDetails opDetails = new TR069OperationDetails();\r
247     opDetails.setOpCode(TR069OperationCode.SET_PARAMETER_VALUES);\r
248 \r
249     return NetconfToTr069MapperUtil.handleParamsOperation(params, opDetails, deviceId);\r
250 \r
251   }\r
252 \r
253   /**\r
254    * @param deviceId\r
255    * @return\r
256    */\r
257   private ConfigurationData getDeviceConfigurationData(String deviceId, String swVersion,\r
258       String hwVersion) {\r
259     String configDBURI = getConfigDBURI();\r
260     logger.debug(\r
261         "Device Configuration to be fetched from Config DB URI: {}, macId {}, swVersion {}, hwVersion {}",\r
262         configDBURI, deviceId, swVersion, hwVersion);\r
263     ConfigurationData configData = null;\r
264     try {\r
265 \r
266       MultiValueMap<String, String> uriParams = new LinkedMultiValueMap<>();\r
267       uriParams.add("macId", deviceId);\r
268       uriParams.add("swVersion", swVersion);\r
269       uriParams.add("hwVersion", hwVersion);\r
270       HttpHeaders headers = new HttpHeaders();\r
271       headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\r
272       final HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(uriParams, headers);\r
273 \r
274       ResponseEntity<ConfigurationData> res =\r
275           restTemplate.postForEntity(configDBURI, entity, ConfigurationData.class);\r
276       configData = res.getBody();\r
277       logger.debug("Successfully retrived config data for device id{} data {}", deviceId,\r
278           configData);\r
279     } catch (Exception e) {\r
280       logger.error("An exception occurred to get the initial device configuration, Reason: {}",\r
281           e.getMessage());\r
282     }\r
283     return configData;\r
284   }\r
285 \r
286   /**\r
287    * @return\r
288    */\r
289   private boolean isPreConfigureOnPnPEnabled() {\r
290     boolean isEnabled = false;\r
291     String preConfigureOnPnP = config.getPreConfigureOnPNP();\r
292     if (preConfigureOnPnP != null && ("true".equalsIgnoreCase(preConfigureOnPnP)\r
293         || "false".equalsIgnoreCase(preConfigureOnPnP))) {\r
294       isEnabled = Boolean.valueOf(preConfigureOnPnP);\r
295     }\r
296 \r
297     return isEnabled;\r
298   }\r
299 \r
300   /**\r
301    * @return\r
302    */\r
303   private String getConfigDBURI() {\r
304     return config.getConfigDBUri();\r
305 \r
306   }\r
307 \r
308   /**\r
309    * it will return the eNodBName if the configuration is imported\r
310    * \r
311    * @return String\r
312    */\r
313   public String getEnodeBName(String deviceId, String swVersion, String hwVersion) {\r
314     String eNodeBName = null;\r
315     if (isPreConfigureOnPnPEnabled()) {\r
316       ConfigurationData configData = getDeviceConfigurationData(deviceId, swVersion, hwVersion);\r
317       if (configData == null || configData.getParameterMONameValueMap().isEmpty()) {\r
318         logger.debug("No configuration exists for the device");\r
319         return eNodeBName;\r
320       }\r
321 \r
322       Map<String, String> paramNameValueMap = configData.getParameterMONameValueMap();\r
323       Iterator<String> iter = paramNameValueMap.keySet().iterator();\r
324       while (iter.hasNext()) {\r
325         String paramName = iter.next();\r
326         if (paramName.endsWith(ENODEB_NAME)) {\r
327           eNodeBName = paramNameValueMap.get(paramName);\r
328           break;\r
329         }\r
330       }\r
331     }\r
332     return eNodeBName;\r
333   }\r
334 }\r