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