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