4d39d5714a8174fe67ed5f2199ce00b7600d0ba6
[oam/tr069-adapter.git] / mapper / src / main / java / org / commscope / tr069adapter / mapper / acs / impl / ACSNotificationHandlerImpl.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.List;\r
23 import org.commscope.tr069adapter.acs.common.DeviceInform;\r
24 import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
25 import org.commscope.tr069adapter.acs.common.InformType;\r
26 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
27 import org.commscope.tr069adapter.acs.common.dto.TR069InformType;\r
28 import org.commscope.tr069adapter.acs.common.inform.BootInform;\r
29 import org.commscope.tr069adapter.acs.common.inform.BootstrapInform;\r
30 import org.commscope.tr069adapter.acs.common.inform.ConnectionRequestInform;\r
31 import org.commscope.tr069adapter.acs.common.inform.PeriodicInform;\r
32 import org.commscope.tr069adapter.acs.common.inform.TransferCompleteInform;\r
33 import org.commscope.tr069adapter.acs.common.inform.ValueChangeInform;\r
34 import org.commscope.tr069adapter.mapper.MOMetaData;\r
35 import org.commscope.tr069adapter.mapper.MapperConfigProperties;\r
36 import org.commscope.tr069adapter.mapper.acs.ACSNotificationHandler;\r
37 import org.commscope.tr069adapter.mapper.dao.DeviceOperationsDAO;\r
38 import org.commscope.tr069adapter.mapper.entity.DeviceOperationDetails;\r
39 import org.commscope.tr069adapter.mapper.model.NetConfServerDetails;\r
40 import org.commscope.tr069adapter.mapper.model.NetconfServerManagementError;\r
41 import org.commscope.tr069adapter.mapper.netconf.NetConfNotificationSender;\r
42 import org.commscope.tr069adapter.mapper.netconf.NetConfServerManager;\r
43 import org.commscope.tr069adapter.mapper.sync.SynchronizedRequestHandler;\r
44 import org.commscope.tr069adapter.mapper.util.FirwareUpgradeErrorCode;\r
45 import org.commscope.tr069adapter.mapper.util.FirwareUpgradeStatus;\r
46 import org.commscope.tr069adapter.mapper.util.MOMetaDataUtil;\r
47 import org.commscope.tr069adapter.mapper.ves.VESNotificationSender;\r
48 import org.slf4j.Logger;\r
49 import org.slf4j.LoggerFactory;\r
50 import org.springframework.beans.factory.annotation.Autowired;\r
51 import org.springframework.stereotype.Component;\r
52 \r
53 @Component\r
54 public class ACSNotificationHandlerImpl implements ACSNotificationHandler {\r
55 \r
56   private static final Logger logger = LoggerFactory.getLogger(ACSNotificationHandlerImpl.class);\r
57   private static final String SOFT_MGMT_NS_URI = "urn:o-ran:software-management:1.0";\r
58 \r
59   @Autowired\r
60   SynchronizedRequestHandler syncHandler;\r
61 \r
62   @Autowired\r
63   MOMetaDataUtil metaDataUtil;\r
64 \r
65   @Autowired\r
66   PnPPreProvisioningHandler pnpPreProvisioningHandler;\r
67 \r
68   @Autowired\r
69   VESNotificationSender vesnotiSender;\r
70 \r
71   @Autowired\r
72   NetConfNotificationSender notiSender;\r
73 \r
74   @Autowired\r
75   MapperConfigProperties config;\r
76 \r
77   @Autowired\r
78   NetConfServerManager netconfManager;\r
79 \r
80   @Autowired\r
81   DeviceOperationsDAO deviceOperDAO;\r
82 \r
83   @Override\r
84   public void handleOperationResponse(DeviceRPCResponse opResult) {\r
85     opResult.getOperationResponse().setParameterDTOs(\r
86         filterUnsupportedParameters(opResult.getOperationResponse().getParameterDTOs(),\r
87             opResult.getDeviceDetails().getSoftwareVersion(),\r
88             opResult.getDeviceDetails().getHardwareVersion()));\r
89     syncHandler.notifyResult(opResult);\r
90   }\r
91 \r
92   @Override\r
93   public void handleNotification(DeviceInform notification) {\r
94     boolean isAlarmVC = isAlarmVC(notification);\r
95 \r
96     if (notification instanceof BootstrapInform) {\r
97       logger.info("BootStrap notification received");\r
98       BootstrapInform bootstrapNotification = (BootstrapInform) notification;\r
99 \r
100       DeviceOperationDetails deviceDetails =\r
101           deviceOperDAO.findByDeviceId(notification.getDeviceDetails().getDeviceId());\r
102       if (deviceDetails == null) {\r
103         deviceDetails = new DeviceOperationDetails();\r
104         deviceDetails.setDeviceId(notification.getDeviceDetails().getDeviceId());\r
105         deviceDetails.setSwVersion(notification.getDeviceDetails().getSoftwareVersion());\r
106         deviceOperDAO.save(deviceDetails);\r
107       }\r
108 \r
109       checkForActivateNotification(notification);\r
110 \r
111       // send request to create the netconf server instance for the bootstrap device\r
112       // id\r
113       NetConfServerDetails serverInfo = createNtConfServer(bootstrapNotification);\r
114       if (serverInfo == null)\r
115         return;\r
116 \r
117       vesnotiSender.sendNotification(bootstrapNotification, serverInfo);\r
118       BootstrapInform bsInform =\r
119           getDeviceBootStrapNotification(bootstrapNotification, TR069InformType.BOOTSTRAP);\r
120       ValueChangeInform vcInform = null;\r
121       if (bootstrapNotification.getValueChangeNotification() != null) {\r
122         logger.info("Bootstrap notification received along with VC");\r
123         vcInform =\r
124             getDeviceValueChangeNotification(bootstrapNotification, TR069InformType.VALUECHANGE);\r
125         processVCNotification(vcInform, isAlarmVC);\r
126       }\r
127       notiSender.sendNotification(bsInform);\r
128       if (vcInform != null)\r
129         processVCNotification(vcInform, isAlarmVC);\r
130     } else if (notification instanceof BootInform) {\r
131       logger.info("Boot notification received");\r
132 \r
133       NetConfServerDetails serverInfo = createNtConfServer(notification);\r
134       if (serverInfo == null)\r
135         return;\r
136 \r
137       checkForActivateNotification(notification);\r
138       BootInform bootNotification = (BootInform) notification;\r
139       BootInform bInform = getDeviceBootNotification(bootNotification, TR069InformType.BOOT);\r
140       ValueChangeInform vcInform = null;\r
141       if (bootNotification.getValueChangeNotification() != null) {\r
142         logger.info("Boot notification received along with VC");\r
143         vcInform = getDeviceValueChangeNotification(bootNotification, TR069InformType.VALUECHANGE);\r
144       }\r
145       notiSender.sendNotification(bInform);\r
146       processVCNotification(vcInform, isAlarmVC);\r
147     } else if (notification instanceof PeriodicInform) {\r
148       PeriodicInform pINotificaiton = (PeriodicInform) notification;\r
149       vesnotiSender.sendNotification(pINotificaiton, null);\r
150       notiSender.sendNotification(pINotificaiton);\r
151       logger.info("PI notification received");\r
152     } else if (notification instanceof ConnectionRequestInform) {\r
153       ConnectionRequestInform crNotificaiton = (ConnectionRequestInform) notification;\r
154       vesnotiSender.sendNotification(crNotificaiton, null);\r
155       logger.info("ConnectionRequestInform notification received");\r
156     } else if (notification instanceof ValueChangeInform) {\r
157       ValueChangeInform valueChgNotificaiton = (ValueChangeInform) notification;\r
158       processVCNotification(valueChgNotificaiton, isAlarmVC);\r
159     } else if (notification instanceof TransferCompleteInform) {\r
160       TransferCompleteInform tfNotificaiton = (TransferCompleteInform) notification;\r
161       if (tfNotificaiton.getCommandKey() != null && tfNotificaiton.getCommandKey()\r
162           .equalsIgnoreCase(tfNotificaiton.getDeviceDetails().getDeviceId())) {\r
163         logger.debug("TransferCompleteInform is recevied at mapper");\r
164         processTransferCompleteInform(tfNotificaiton);\r
165         logger.debug("TransferCompleteInform processing completed at mapper");\r
166       }\r
167     }\r
168 \r
169     pnpPreProvisioningHandler.onDeviceNotification(notification);\r
170   }\r
171 \r
172   private NetConfServerDetails createNtConfServer(DeviceInform inform) {\r
173     String eNodeBName = pnpPreProvisioningHandler.getEnodeBName(\r
174         inform.getDeviceDetails().getDeviceId(), inform.getDeviceDetails().getSoftwareVersion(),\r
175         inform.getDeviceDetails().getHardwareVersion());\r
176     if (eNodeBName == null)\r
177       eNodeBName = inform.getDeviceDetails().getDeviceId();\r
178     NetConfServerDetails serverInfo =\r
179         netconfManager.createNetconfServer(inform.getDeviceDetails().getDeviceId(), eNodeBName,\r
180             inform.getDeviceDetails().getSoftwareVersion(),\r
181             inform.getDeviceDetails().getHardwareVersion());\r
182     if (serverInfo != null && !NetconfServerManagementError.SUCCESS.equals(serverInfo.getError())) {\r
183       logger.error("Failed to handle boot/bootstrap notification. Server INFO: {}", serverInfo);\r
184       logger.error("Failed to create the netconf server for device ID: {}  Error: {}",\r
185           inform.getDeviceDetails().getDeviceId(), serverInfo.getError());\r
186       return null;\r
187     } else if (serverInfo == null) {\r
188       logger.error(\r
189           "Failed to handle bootstrap notification. Failed to create netconf server. serverInfo is null");\r
190       return null;\r
191     }\r
192     return serverInfo;\r
193   }\r
194 \r
195   private void processVCNotification(ValueChangeInform valueChgNotificaiton, boolean isAlarmVC) {\r
196     if (isAlarmVC) {\r
197       logger.debug("Alarm VC received forwarding to VES Collector");\r
198       vesnotiSender.sendNotification(valueChgNotificaiton, null);\r
199     } else {\r
200       logger.info("VC notification received");\r
201       notiSender.sendNotification(valueChgNotificaiton);\r
202     }\r
203   }\r
204 \r
205   private boolean isAlarmVC(DeviceInform notification) {\r
206     if (null != notification && null != notification.getParameters()) {\r
207       for (ParameterDTO param : notification.getParameters()) {\r
208         if (param.getParamName().matches(config.getAlarmMORegex())) {\r
209           logger.debug("This VC contains alarm MOs");\r
210           return true;\r
211         }\r
212       }\r
213     }\r
214     return false;\r
215   }\r
216 \r
217   public List<ParameterDTO> filterUnsupportedParameters(List<ParameterDTO> parameters,\r
218       String swVersion, String hwVersion) {\r
219     List<ParameterDTO> result = new ArrayList<>();\r
220     if (null != parameters) {\r
221       for (ParameterDTO param : parameters) {\r
222         MOMetaData metaData =\r
223             metaDataUtil.getMetaDataByTR69Name(param.getParamName(), swVersion, hwVersion);\r
224         if (null != metaData) {\r
225           result.add(param);\r
226         }\r
227       }\r
228     }\r
229     return result;\r
230   }\r
231 \r
232   public static BootstrapInform getDeviceBootStrapNotification(DeviceInform devNotification,\r
233       TR069InformType notificationType) {\r
234     BootstrapInform bsInform = new BootstrapInform();\r
235     List<InformType> informTypeList = new ArrayList<>();\r
236     informTypeList.add(notificationType);\r
237     bsInform.setDeviceDetails(devNotification.getDeviceDetails());\r
238     bsInform.setInformTypeList(informTypeList);\r
239     List<ParameterDTO> paramList = new ArrayList<>();\r
240     for (ParameterDTO param : devNotification.getParameters()) {\r
241       paramList.add(new ParameterDTO(param.getParamName(), param.getParamValue()));\r
242     }\r
243     bsInform.setParameters(paramList);\r
244     return bsInform;\r
245   }\r
246 \r
247   public static BootInform getDeviceBootNotification(DeviceInform devNotification,\r
248       TR069InformType notificationType) {\r
249     BootInform bInform = new BootInform();\r
250     List<InformType> informTypeList = new ArrayList<>();\r
251     informTypeList.add(notificationType);\r
252     bInform.setDeviceDetails(devNotification.getDeviceDetails());\r
253     bInform.setInformTypeList(informTypeList);\r
254     List<ParameterDTO> paramList = new ArrayList<>();\r
255     for (ParameterDTO param : devNotification.getParameters()) {\r
256       paramList.add(new ParameterDTO(param.getParamName(), param.getParamValue()));\r
257     }\r
258     bInform.setParameters(paramList);\r
259     return bInform;\r
260   }\r
261 \r
262   public static ValueChangeInform getDeviceValueChangeNotification(DeviceInform devNotification,\r
263       TR069InformType notificationType) {\r
264     ValueChangeInform devValChangeNotif = new ValueChangeInform();\r
265     List<InformType> informTypeList = new ArrayList<>();\r
266     informTypeList.add(notificationType);\r
267     devValChangeNotif.setDeviceDetails(devNotification.getDeviceDetails());\r
268     devValChangeNotif.setInformTypeList(informTypeList);\r
269     List<ParameterDTO> paramList = new ArrayList<>();\r
270     for (ParameterDTO param : devNotification.getParameters()) {\r
271       paramList.add(new ParameterDTO(param.getParamName(), param.getParamValue()));\r
272     }\r
273     devValChangeNotif.setParameters(paramList);\r
274     devValChangeNotif.setExternalIPAddress(getExternalIPAddress(devNotification.getParameters()));\r
275     return devValChangeNotif;\r
276   }\r
277 \r
278   private static String getExternalIPAddress(List<ParameterDTO> params) {\r
279     ParameterDTO[] nbiParam = params.toArray(new ParameterDTO[params.size()]);\r
280     String externalIpAddress = "";\r
281     boolean isIPv6 = isIPv6Enabled(nbiParam);\r
282 \r
283     for (int index1 = 0; index1 < nbiParam.length; index1++) {\r
284 \r
285       if (isIPv6) {\r
286         if (nbiParam[index1].getParamName().contains("IPv6Address")\r
287             || nbiParam[index1].getParamName().contains(".1.IPInterfaceIPAddress")) {\r
288           externalIpAddress = nbiParam[index1].getParamValue();\r
289           logger.debug("device communicating is with IPV6 address");\r
290         }\r
291       } else {\r
292         if (nbiParam[index1].getParamName().contains("IPv4Address")\r
293             || nbiParam[index1].getParamName().contains("ExternalIPAddress")\r
294             || nbiParam[index1].getParamName().contains(".1.IPInterfaceIPAddress")) {\r
295           externalIpAddress = nbiParam[index1].getParamValue();\r
296         }\r
297       }\r
298       if (externalIpAddress.trim().length() > 0)\r
299         break;\r
300     }\r
301     return externalIpAddress;\r
302   }\r
303 \r
304   private static boolean isIPv6Enabled(ParameterDTO[] nbiParam) {\r
305     boolean isIPv6 = false;\r
306     for (int index1 = 0; index1 < nbiParam.length; index1++) {\r
307       if (nbiParam[index1].getParamName().contains("IPv6Enable")\r
308           && nbiParam[index1].getParamValue().equalsIgnoreCase("1")) {\r
309         isIPv6 = true;\r
310         break;\r
311       }\r
312     }\r
313     return isIPv6;\r
314   }\r
315 \r
316   private void processTransferCompleteInform(TransferCompleteInform notification) {\r
317 \r
318     try {\r
319       ArrayList<ParameterDTO> paramList = new ArrayList<ParameterDTO>();\r
320       DeviceOperationDetails fwDetails =\r
321           deviceOperDAO.findByDeviceId(notification.getDeviceDetails().getDeviceId());\r
322       if (fwDetails == null || fwDetails.getFileName() == null) {\r
323         logger.debug(\r
324             "TransferCompleteInform recevied for invaild device, there is no entry exist in the database");\r
325         return;\r
326       }\r
327       if (fwDetails.getDownLoadStatus() == FirwareUpgradeStatus.DOWNLOAD_INTIATED.getStatus()) {\r
328         paramList.add(new ParameterDTO("download-event.file-name", fwDetails.getFileName()));\r
329 \r
330         String status = FirwareUpgradeErrorCode.getErrorCodeMapping(notification.getFaultCode());\r
331         paramList.add(new ParameterDTO("download-event.status", status));\r
332         if (notification.getFaultCode() != 0) {\r
333           fwDetails.setDownLoadStatus(FirwareUpgradeStatus.DOWNLOAD_FAILED.getStatus());\r
334           paramList\r
335               .add(new ParameterDTO("download-event.error-message", notification.getFaultString()));\r
336         } else {\r
337           fwDetails.setDownLoadStatus(FirwareUpgradeStatus.DOWNLOAD_COMPLETED.getStatus());\r
338           logger.debug("downloading file completed on the device successfully.");\r
339         }\r
340         deviceOperDAO.save(fwDetails);\r
341 \r
342         logger.debug("sending download-event notification to netconfserver");\r
343 \r
344         if (notiSender.sendCustomNotification(notification.getDeviceDetails().getDeviceId(),\r
345             paramList, SOFT_MGMT_NS_URI).getStatusCode().is2xxSuccessful()) {\r
346           logger.debug("sending download-event notification to netconfserver sucess");\r
347         } else {\r
348           logger.error("sending download-event notification to netconfserver failed");\r
349         }\r
350       } else {\r
351         logger.debug(\r
352             "TransferCompleteInform recevied after boot is received; already software is activated");\r
353       }\r
354     } catch (Exception e) {\r
355       logger.debug("Exception occured while processing TransferCompleteInform " + e.toString());\r
356     }\r
357   }\r
358 \r
359   private void checkForActivateNotification(DeviceInform notification) {\r
360 \r
361     try {\r
362       ArrayList<ParameterDTO> paramList = new ArrayList<ParameterDTO>();\r
363       DeviceOperationDetails devDetails =\r
364           deviceOperDAO.findByDeviceId(notification.getDeviceDetails().getDeviceId());\r
365 \r
366       if (devDetails == null\r
367           || devDetails.getDownLoadStatus() == FirwareUpgradeStatus.NOT_STARTED.getStatus()) {\r
368         logger.debug("firmware upgrade is not in progress");\r
369         return;\r
370       }\r
371 \r
372       if (!notification.getDeviceDetails().getSoftwareVersion()\r
373           .equalsIgnoreCase(devDetails.getSwVersion())\r
374           && devDetails.getDownLoadStatus() == FirwareUpgradeStatus.DOWNLOAD_INTIATED.getStatus()) {\r
375         logger.debug("received the boot/bootstrap before the transfer complete recevied");\r
376         TransferCompleteInform inform = new TransferCompleteInform();\r
377         inform.setDeviceDetails(notification.getDeviceDetails());\r
378         inform.setFaultCode(0);\r
379         processTransferCompleteInform(inform);\r
380       }\r
381 \r
382       devDetails = deviceOperDAO.findByDeviceId(notification.getDeviceDetails().getDeviceId());\r
383       if (devDetails.getDownLoadStatus() == FirwareUpgradeStatus.DOWNLOAD_COMPLETED.getStatus()) {\r
384         paramList.add(new ParameterDTO("activation-event.slot-name", "Active-Partion"));\r
385         // check for software change\r
386         if (notification.getDeviceDetails().getSoftwareVersion()\r
387             .equalsIgnoreCase(devDetails.getSwVersion())) {\r
388           paramList.add(new ParameterDTO("activation-event.status", "APPLICATION_ERROR"));\r
389           paramList.add(new ParameterDTO("activation-event.error-message",\r
390               "Same Software Version is reported after upgrade"));\r
391           devDetails.setDownLoadStatus(FirwareUpgradeStatus.ACTIVATION_ERROR.getStatus());\r
392         } else {\r
393           devDetails.setSwVersion(notification.getDeviceDetails().getSoftwareVersion());\r
394           devDetails.setDownLoadStatus(FirwareUpgradeStatus.ACTIVATION_COMPLETED.getStatus());\r
395           paramList.add(new ParameterDTO("activation-event.status", "COMPLETED"));\r
396         }\r
397         deviceOperDAO.save(devDetails);\r
398 \r
399         logger.debug("sending activation-event notification to netconfserver");\r
400 \r
401         if (notiSender.sendCustomNotification(notification.getDeviceDetails().getDeviceId(),\r
402             paramList, SOFT_MGMT_NS_URI).getStatusCode().is2xxSuccessful()) {\r
403           logger.debug("sending activation-event notification to netconfserver sucess");\r
404         } else {\r
405           logger.error("sending activation-event notification to netconfserver failed");\r
406         }\r
407       }\r
408     } catch (Exception e) {\r
409       logger.debug(\r
410           "Exception occured while processing ProcessFirmWareActivateNotification " + e.toString());\r
411     }\r
412   }\r
413 }\r