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