Initial source code
[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 \r
26 import org.commscope.tr069adapter.acs.common.DeviceInform;\r
27 import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
28 import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
29 import org.commscope.tr069adapter.acs.common.OperationOptions;\r
30 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
31 import org.commscope.tr069adapter.acs.common.dto.ConfigurationData;\r
32 import org.commscope.tr069adapter.acs.common.dto.TR069DeviceDetails;\r
33 import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
34 import org.commscope.tr069adapter.acs.common.dto.TR069OperationDetails;\r
35 import org.commscope.tr069adapter.acs.common.inform.BootInform;\r
36 import org.commscope.tr069adapter.acs.common.inform.BootstrapInform;\r
37 import org.commscope.tr069adapter.mapper.MOMetaData;\r
38 import org.commscope.tr069adapter.mapper.MapperConfigProperties;\r
39 import org.commscope.tr069adapter.mapper.sync.SynchronizedRequestHandler;\r
40 import org.commscope.tr069adapter.mapper.util.MOMetaDataUtil;\r
41 import org.slf4j.Logger;\r
42 import org.slf4j.LoggerFactory;\r
43 import org.slf4j.MDC;\r
44 import org.springframework.beans.factory.annotation.Autowired;\r
45 import org.springframework.stereotype.Component;\r
46 import org.springframework.util.StringUtils;\r
47 import org.springframework.web.client.RestTemplate;\r
48 \r
49 @Component\r
50 public class PnPPreProvisioningHandler {\r
51 \r
52   private static final Logger logger = LoggerFactory.getLogger(PnPPreProvisioningHandler.class);\r
53 \r
54   private static String clientString = "client";\r
55   private static final String ADMIN_STATE = "AdminState";\r
56   private static final String ENODEB_NAME = "X_0005B9_eNBName";\r
57 \r
58   @Autowired\r
59   SynchronizedRequestHandler syncHandler;\r
60 \r
61   @Autowired\r
62   MOMetaDataUtil moMetaDataUtil;\r
63 \r
64   @Autowired\r
65   MapperConfigProperties config;\r
66 \r
67   private RestTemplate restTemplate = new RestTemplate();\r
68 \r
69   /**\r
70    * @param notification\r
71    */\r
72   public void onDeviceNotification(DeviceInform notification) {\r
73     String deviceId = null;\r
74     try {\r
75       if (notification instanceof BootstrapInform || notification instanceof BootInform) {\r
76         logger.debug("Checking whether the PnP pre-configuration is enabled");\r
77         if (isPreConfigureOnPnPEnabled()) {\r
78           logger.info(\r
79               "Pre-configuration during Bootstrap or Boot is enabled, hence the configuration imported in Config DB shall be provisioned to the device");\r
80         } else {\r
81           logger.debug("Pre-configuration on PnP is disabled!!!");\r
82           return;\r
83         }\r
84       }\r
85 \r
86       if (notification instanceof BootstrapInform) {\r
87         BootstrapInform bootstrapNotification = (BootstrapInform) notification;\r
88         deviceId = bootstrapNotification.getDeviceDetails().getDeviceId();\r
89         MDC.put(clientString, deviceId);\r
90         logger.info("Bootstrap notification received");\r
91         performPreProvisioning(deviceId, false);\r
92 \r
93       } else if (notification instanceof BootInform) {\r
94         BootInform bootNotification = (BootInform) notification;\r
95         deviceId = bootNotification.getDeviceDetails().getDeviceId();\r
96         MDC.put(clientString, deviceId);\r
97         logger.info("Boot notification received");\r
98 \r
99         performPreProvisioning(deviceId, true);\r
100       }\r
101 \r
102       logger.debug("Successfully completed provisioning of PnP mandatory parameters");\r
103     } finally {\r
104       MDC.remove(clientString);\r
105     }\r
106   }\r
107 \r
108   /**\r
109    * @param deviceId\r
110    * @param isBoot\r
111    */\r
112   private void performPreProvisioning(String deviceId, boolean isBoot) {\r
113     List<DeviceRPCRequest> deviceRPCRequestList =\r
114         prepareNBIDeviceOperationrequest(deviceId, isBoot);\r
115     if (deviceRPCRequestList.isEmpty()) {\r
116       logger.debug("No Operation requests exists to perform pre provision on the device");\r
117       return;\r
118     }\r
119 \r
120     boolean isMandatoryProvFailed = false;\r
121     for (DeviceRPCRequest deviceRPCRequest : deviceRPCRequestList) {\r
122       logger.info("Performing PROVISION operation");\r
123       DeviceRPCResponse deviceRPCResponse = syncHandler.performDeviceOperation(deviceRPCRequest);\r
124       logger.debug("Received Provisioning Operation result");\r
125       if (deviceRPCResponse == null || !StringUtils.isEmpty(deviceRPCResponse.getFaultString())) {\r
126         logger.error("Device operation failed, Reason: {}",\r
127             ((deviceRPCResponse == null) ? "Null Operation result"\r
128                 : deviceRPCResponse.getFaultString()));\r
129         isMandatoryProvFailed = true;\r
130         break;\r
131       }\r
132 \r
133       logger.debug("Provisioning is successful");\r
134     }\r
135 \r
136     if (isMandatoryProvFailed) {\r
137       logger\r
138           .debug("Mandatory provisioning has failed, hence provisioning Admin down on the device");\r
139       provisionAdminDown(deviceRPCRequestList);\r
140       logger.debug("AdminDown Provisioning is successful");\r
141     }\r
142   }\r
143 \r
144   private void provisionAdminDown(List<DeviceRPCRequest> deviceRPCRequestList) {\r
145     DeviceRPCRequest adminDownOpRequest = null;\r
146     for (DeviceRPCRequest nbiDeviceOperationRequest : deviceRPCRequestList) {\r
147       ParameterDTO param = nbiDeviceOperationRequest.getOpDetails().getParmeters().get(0);\r
148       if (param.getParamName().endsWith(ADMIN_STATE)) {\r
149         adminDownOpRequest = nbiDeviceOperationRequest;\r
150         break;\r
151       }\r
152     }\r
153     if (adminDownOpRequest != null) {\r
154       List<ParameterDTO> adminDownParams = adminDownOpRequest.getOpDetails().getParmeters();\r
155       for (ParameterDTO adminDownParam : adminDownParams) {\r
156         adminDownParam.setParamValue("0");\r
157       }\r
158       DeviceRPCResponse deviceRPCResponse = syncHandler.performDeviceOperation(adminDownOpRequest);\r
159       if (deviceRPCResponse == null || !StringUtils.isEmpty(deviceRPCResponse.getFaultString())) {\r
160         logger.error("Device operation failed, Reason: {}",\r
161             ((deviceRPCResponse == null) ? "Null Operation result"\r
162                 : deviceRPCResponse.getFaultString()));\r
163       }\r
164     }\r
165   }\r
166 \r
167   /**\r
168    * @param deviceId\r
169    * @param isBoot\r
170    * @return\r
171    */\r
172   private List<DeviceRPCRequest> prepareNBIDeviceOperationrequest(String deviceId, boolean isBoot) {\r
173     logger.debug("Preparing the NBI Device Operation Request");\r
174     List<DeviceRPCRequest> deviceRPCRequestList = new ArrayList<>();\r
175 \r
176     ConfigurationData configData = getDeviceConfigurationData(deviceId);\r
177     if (configData == null || configData.getParameterMONameValueMap().isEmpty()) {\r
178       logger.debug("No configuration exists for the device");\r
179       return deviceRPCRequestList;\r
180     }\r
181 \r
182     List<ParameterDTO> configParams = new ArrayList<>();\r
183     List<ParameterDTO> adminStateParams = new ArrayList<>();\r
184     Map<String, String> paramNameValueMap = configData.getParameterMONameValueMap();\r
185     Iterator<String> iter = paramNameValueMap.keySet().iterator();\r
186     while (iter.hasNext()) {\r
187       String paramName = iter.next();\r
188       String paramValue = paramNameValueMap.get(paramName);\r
189       MOMetaData moMetaData = moMetaDataUtil.getMetaDataByTR69Name(paramName);\r
190       if ((isBoot && !paramName.endsWith(ADMIN_STATE)) || moMetaData == null)\r
191         continue;\r
192       ParameterDTO parameterDTO = getParameterDTO(paramName, paramValue, moMetaData);\r
193 \r
194       if (paramName.endsWith(ADMIN_STATE)) {\r
195         adminStateParams.add(parameterDTO);\r
196       } else {\r
197         configParams.add(parameterDTO);\r
198       }\r
199       logger.debug("Param -> {} Param Value: {}", paramName, paramValue);\r
200     }\r
201 \r
202     if (configParams.isEmpty() && adminStateParams.isEmpty()) {\r
203       logger.debug("Empty parameters list from config db, hence not performing pre-provision");\r
204       return deviceRPCRequestList;\r
205     }\r
206 \r
207     if (!configParams.isEmpty()) {\r
208       deviceRPCRequestList.add(createNBIOperationRequest(deviceId, configParams));\r
209     }\r
210 \r
211     if (!adminStateParams.isEmpty()) {\r
212       deviceRPCRequestList.add(createNBIOperationRequest(deviceId, adminStateParams));\r
213     }\r
214 \r
215     return deviceRPCRequestList;\r
216   }\r
217 \r
218   private ParameterDTO getParameterDTO(String paramName, String paramValue, MOMetaData moMetaData) {\r
219     String dataType = moMetaData.getDataType();\r
220     if (dataType.equals("boolean")) {\r
221       if (paramValue.equalsIgnoreCase("true")) {\r
222         paramValue = "1";\r
223       } else if (paramValue.equalsIgnoreCase("false")) {\r
224         paramValue = "0";\r
225       }\r
226     }\r
227     ParameterDTO parameterDTO = new ParameterDTO(paramName, paramValue);\r
228     parameterDTO.setDataType(dataType);\r
229 \r
230     return parameterDTO;\r
231   }\r
232 \r
233   /**\r
234    * @param deviceId\r
235    * @param params\r
236    * @return\r
237    */\r
238   private DeviceRPCRequest createNBIOperationRequest(String deviceId, List<ParameterDTO> params) {\r
239     TR069OperationDetails opDetails = new TR069OperationDetails();\r
240     opDetails.setOpCode(TR069OperationCode.SET_PARAMETER_VALUES);\r
241     opDetails.setParmeters(params);\r
242 \r
243     DeviceRPCRequest deviceRPCRequest = new DeviceRPCRequest();\r
244     TR069DeviceDetails tr069DeviceDetails = new TR069DeviceDetails();\r
245     tr069DeviceDetails.setDeviceId(deviceId);\r
246     deviceRPCRequest.setOpDetails(opDetails);\r
247     deviceRPCRequest.setDeviceDetails(tr069DeviceDetails);\r
248     OperationOptions options = new OperationOptions();\r
249     options.setExecutionTimeout(300l);\r
250     deviceRPCRequest.setOptions(options);\r
251 \r
252     return deviceRPCRequest;\r
253   }\r
254 \r
255   /**\r
256    * @param deviceId\r
257    * @return\r
258    */\r
259   private ConfigurationData getDeviceConfigurationData(String deviceId) {\r
260     String configDBURI = getConfigDBURI();\r
261     logger.debug("Device Configuration to be fetched from Config DB URI: {}", configDBURI);\r
262     ConfigurationData configData = null;\r
263     try {\r
264       configData = restTemplate.getForObject(configDBURI + deviceId, ConfigurationData.class);\r
265     } catch (Exception e) {\r
266       logger.error("An exception occurred to get the initial device configuration, Reason: {}",\r
267           e.getMessage());\r
268     }\r
269     return configData;\r
270   }\r
271 \r
272   /**\r
273    * @return\r
274    */\r
275   private boolean isPreConfigureOnPnPEnabled() {\r
276     boolean isEnabled = false;\r
277     String preConfigureOnPnP = config.getPreConfigureOnPNP();\r
278     if (preConfigureOnPnP != null && ("true".equalsIgnoreCase(preConfigureOnPnP)\r
279         || "false".equalsIgnoreCase(preConfigureOnPnP))) {\r
280       isEnabled = Boolean.valueOf(preConfigureOnPnP);\r
281     }\r
282 \r
283     return isEnabled;\r
284   }\r
285 \r
286   /**\r
287    * @return\r
288    */\r
289   private String getConfigDBURI() {\r
290     return config.getConfigDBUri();\r
291 \r
292   }\r
293 \r
294   /**\r
295    * it will return the eNodBName if the configuration is imported\r
296    * \r
297    * @return String\r
298    */\r
299   public String getEnodeBName(String deviceId) {\r
300     String eNodeBName = null;\r
301     if (isPreConfigureOnPnPEnabled()) {\r
302       ConfigurationData configData = getDeviceConfigurationData(deviceId);\r
303       if (configData == null || configData.getParameterMONameValueMap().isEmpty()) {\r
304         logger.debug("No configuration exists for the device");\r
305         return eNodeBName;\r
306       }\r
307 \r
308       Map<String, String> paramNameValueMap = configData.getParameterMONameValueMap();\r
309       Iterator<String> iter = paramNameValueMap.keySet().iterator();\r
310       while (iter.hasNext()) {\r
311         String paramName = iter.next();\r
312         if (paramName.endsWith(ENODEB_NAME)) {\r
313           eNodeBName = paramNameValueMap.get(paramName);\r
314           break;\r
315         }\r
316       }\r
317     }\r
318     return eNodeBName;\r
319   }\r
320 }\r