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