d8a052f7f68f5055e3ab2da179785d555fedf0be
[ccsdk/features.git] /
1 /*******************************************************************************
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf;
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import javax.annotation.Nonnull;
24 import javax.annotation.Nullable;
25
26 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.internalTypes.InternalDateAndTime;
27 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.internalTypes.InternalSeverity;
28 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.container.AllPm;
29 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.container.Capabilities;
30 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.container.ONFLayerProtocolName;
31 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.util.GenericTransactionUtils;
32 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.wrapperc.OnfMicrowaveModel;
33 import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.toggleAlarmFilter.NotificationDelayService;
34 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.ProviderClient;
35 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.database.service.HtDatabaseEventsService;
36 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.listener.NetconfEventListener12;
37 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.AttributeValueChangedNotificationXml;
38 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml;
39 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.WebSocketServiceClient;
40 import org.onap.ccsdk.features.sdnr.wt.devicemanager.maintenance.MaintenanceService;
41 import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.database.types.EsHistoricalPerformance15Minutes;
42 import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.database.types.EsHistoricalPerformance24Hours;
43 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
44 import org.opendaylight.controller.md.sal.binding.api.MountPoint;
45 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
46 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
47 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.UniversalId;
48 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.extension.g.Extension;
49 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.logical.termination.point.g.Lp;
50 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.g._874._1.model.rev170320.GranularityPeriodType;
51 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.g._874._1.model.rev170320.OtnHistoryDataG;
52 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac;
53 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.network.element.pac.NetworkElementCurrentProblems;
54 import org.opendaylight.yangtools.concepts.ListenerRegistration;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.opendaylight.yangtools.yang.binding.NotificationListener;
57 import org.opendaylight.yangtools.yang.common.QName;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 import com.google.common.base.Optional;
62
63 /**
64  * Get information over NETCONF device according to ONF Coremodel. Read networkelement and
65  * conditional packages.
66  *
67  * Get conditional packages from Networkelement Possible interfaces are: MWPS, LTP(MWPS-TTP),
68  * MWAirInterfacePac, MicrowaveModel-ObjectClasses-AirInterface ETH-CTP,LTP(Client),
69  * MW_EthernetContainer_Pac MWS, LTP(MWS-CTP-xD), MWAirInterfaceDiversityPac,
70  * MicrowaveModel-ObjectClasses-AirInterfaceDiversity MWS, LTP(MWS-TTP),
71  * ,MicrowaveModel-ObjectClasses-HybridMwStructure MWS, LTP(MWS-TTP),
72  * ,MicrowaveModel-ObjectClasses-PureEthernetStructure
73  *
74  * @author herbert
75  *
76  */
77 @SuppressWarnings("deprecation")
78 public class ONFCoreNetworkElement12Microwave extends ONFCoreNetworkElement12Base
79         implements ONFCoreNetworkElementCallback, NotificationActor<AttributeValueChangedNotificationXml> {
80
81     private static final Logger LOG = LoggerFactory.getLogger(ONFCoreNetworkElement12Microwave.class);
82
83     /*-----------------------------------------------------------------------------
84      * Class members
85      */
86     private final @Nonnull NetconfEventListener12 microwaveEventListener;
87     private final @Nonnull OnfMicrowaveModel microwaveModel;
88     private final NotificationWorker<AttributeValueChangedNotificationXml> notificationQueue;
89
90     private ListenerRegistration<NotificationListener> listenerRegistrationresult = null;
91
92     /*-----------------------------------------------------------------------------
93      * Construction
94      */
95
96     /**
97      * Constructor
98      *
99      * @param mountPointNodeName as String
100      * @param capabilities of the specific network element
101      * @param netconfNodeDataBroker for the network element specific data
102      * @param webSocketService to forward event notifications
103      * @param databaseService to access the database
104      * @param dcaeProvider to forward problem / change notifications
105      */
106     ONFCoreNetworkElement12Microwave(String mountPointNodeName, Capabilities capabilities,
107             DataBroker netconfNodeDataBroker, WebSocketServiceClient webSocketService,
108             HtDatabaseEventsService databaseService, ProviderClient dcaeProvider, @Nullable ProviderClient aotsmClient,
109             MaintenanceService maintenanceService,
110             NotificationDelayService<ProblemNotificationXml> notificationDelayService,
111             OnfMicrowaveModel onfMicrowaveModel) {
112
113         super(mountPointNodeName, netconfNodeDataBroker, capabilities);
114
115         this.microwaveModel = onfMicrowaveModel;
116         this.microwaveModel.setCoreData(this);
117
118         // Create MicrowaveService here
119         this.microwaveEventListener = new NetconfEventListener12(mountPointNodeName, webSocketService,
120                 databaseService, dcaeProvider, aotsmClient, maintenanceService, notificationDelayService, this);
121         this.microwaveModel.setOnfMicrowaveModelListener(microwaveEventListener);
122
123         this.notificationQueue = new NotificationWorker<>(1, 100, this);
124
125         // ->Below shifted to super class
126         // this.isNetworkElementCurrentProblemsSupporting12 =
127         // capabilities.isSupportingNamespaceAndRevision(NetworkElementPac.QNAME);
128         // LOG.debug("support necurrent-problem-list=" + this.isNetworkElementCurrentProblemsSupporting12);
129         // LOG.info("Create NE instance {}", InstanceList.QNAME.getLocalName());
130
131     }
132
133     /*-----------------------------------------------------------------------------
134      * Functions
135      */
136
137     /**
138      * DeviceMonitor Prepare check by updating NE state and reading all interfaces.
139      */
140     @Override
141     public void prepareCheck() {
142         synchronized (dmLock) {
143             boolean change = readNetworkElementAndInterfaces();
144             if (change) {
145                 int problems = microwaveEventListener.removeAllCurrentProblemsOfNode();
146                 List<ProblemNotificationXml> resultList = readAllCurrentProblemsOfNode();
147                 microwaveEventListener.initCurrentProblemStatus(resultList);
148                 LOG.info("Resync mountpoint {} for device {}. Removed {}. Current problems: {}", getMountPointNodeName(),
149                         getUuId(), problems, resultList.size());
150             }
151         }
152     }
153
154     // public boolean checkIfConnectionToMediatorIsOk() -> Shifted to super class
155     // public boolean checkIfConnectionToNeIsOk() -> Shifted to super class
156
157     /*-----------------------------------------------------------------------------
158      * Synchronization
159      */
160
161     // public void initSynchronizationExtension() -> Shifted to super class
162     // private InstanceList readPTPClockInstances() -> Shifted to super class
163
164     /*-----------------------------------------------------------------------------
165      * Services for NE/Device synchronization
166      */
167
168     /**
169      * Handling of specific Notifications from NE, indicating changes and need for synchronization.
170      *
171      * <attribute-value-changed-notification xmlns="urn:onf:params:xml:ns:yang:microwave-model">
172      * <attribute-name>/equipment-pac/equipment-current-problems</attribute-name>
173      * <object-id-ref>CARD-1.1.1.0</object-id-ref> <new-value></new-value>
174      * </attribute-value-changed-notification>
175      * <attribute-value-changed-notification xmlns="urn:onf:params:xml:ns:yang:microwave-model">
176      * <attribute-name>/network-element/extension[value-name="top-level-equipment"]/value</attribute-name>
177      * <object-id-ref>Hybrid-Z</object-id-ref>
178      * <new-value>SHELF-1.1.0.0,IDU-1.55.0.0,ODU-1.56.0.0,IDU-1.65.0.0</new-value>
179      * </attribute-value-changed-notification>
180      */
181
182
183     @Override
184     public void notificationFromNeListener(AttributeValueChangedNotificationXml notificationXml) {
185         notificationQueue.put(notificationXml);
186     }
187
188     @Override
189     public void notificationActor(AttributeValueChangedNotificationXml notificationXml) {
190
191         LOG.debug("Enter change notification listener");
192         if (LOG.isTraceEnabled()) {
193             LOG.trace("Notification: {}", notificationXml);
194         }
195         if (notificationXml.getAttributeName().equals("/equipment-pac/equipment-current-problems")) {
196             syncEquipmentPac(notificationXml.getObjectId());
197         } else if (notificationXml.getAttributeName()
198                 .equals("/network-element/extension[value-name=\"top-level-equipment\"]/value")) {
199             initialReadFromNetworkElement();
200         }
201         LOG.debug("Leave change notification listener");
202     }
203
204     /**
205      * Synchronize problems for a specific equipment-pac
206      *
207      * @param uuidString of the equipment-pac
208      */
209     private synchronized void syncEquipmentPac(String uuidString) {
210
211         int problems = microwaveEventListener.removeObjectsCurrentProblemsOfNode(uuidString);
212         LOG.debug("Removed {} problems for uuid {}", problems, uuidString);
213
214         List<ProblemNotificationXml> resultList = getEquipment().addProblemsofNodeObject(uuidString);
215         microwaveEventListener.initCurrentProblemStatus(resultList);
216         LOG.debug("Added {} problems for uuid {}", resultList.size(), uuidString);
217
218     }
219
220
221     /*-----------------------------------------------------------------------------
222      * Problem/Fault related functions
223      */
224
225     /**
226      * Read during startup all relevant structure and status parameters from device
227      */
228     @Override
229     public synchronized void initialReadFromNetworkElement() {
230         // optionalNe.getLtp().get(0).getLp();
231         LOG.debug("Get info about {}", getMountPointNodeName());
232
233         int problems = microwaveEventListener.removeAllCurrentProblemsOfNode();
234         LOG.debug("Removed all {} problems from database at registration", problems);
235
236         // Step 2.1: access data broker within this mount point
237         LOG.debug("DBRead start");
238
239         // Step 2.2: read ne from data store
240         readNetworkElementAndInterfaces();
241         getEquipment().readNetworkElementEquipment();
242
243         // Step 2.3: read the existing faults and add to DB
244         List<ProblemNotificationXml> resultList = readAllCurrentProblemsOfNode();
245         getEquipment().addProblemsofNode(resultList);
246
247         microwaveEventListener.initCurrentProblemStatus(resultList);
248
249         microwaveEventListener.writeEquipment(getEquipment());
250
251         LOG.info("Found info at {} for device {} number of problems: {}", getMountPointNodeName(), getUuId(),
252                 resultList.size());
253     }
254
255     /**
256      * LOG the newly added problems of the interface pac
257      *
258      * @param idxStart
259      * @param uuid
260      * @param resultList
261      */
262     private void debugResultList(String uuid, List<ProblemNotificationXml> resultList, int idxStart) {
263         if (LOG.isDebugEnabled()) {
264             StringBuffer sb = new StringBuffer();
265             int idx = 0;
266             for (int t = idxStart; t < resultList.size(); t++) {
267                 sb.append(idx++);
268                 sb.append(":{");
269                 sb.append(resultList.get(t));
270                 sb.append('}');
271             }
272             LOG.debug("Found problems {} {}", uuid, sb.toString());
273         }
274     }
275
276     /**
277      * Read current problems of AirInterfaces and EthernetContainer according to NE status into DB
278      *
279      * @return List with all problems
280      */
281     @Override
282         protected List<ProblemNotificationXml> readAllCurrentProblemsOfNode() {
283
284         // Step 2.3: read the existing faults and add to DB
285         List<ProblemNotificationXml> resultList = new ArrayList<>();
286         int idxStart; // Start index for debug messages
287         UniversalId uuid;
288
289         synchronized (getPmLock()) {
290             for (Lp lp : getInterfaceList()) {
291
292                 idxStart = resultList.size();
293                 uuid = lp.getUuid();
294                 Class<?> lpClass = getLpExtension(lp);
295
296                 ONFLayerProtocolName lpName = ONFLayerProtocolName.valueOf(lp.getLayerProtocolName());
297
298                 microwaveModel.readTheFaultsOfMicrowaveModel(lpName, lpClass, uuid, resultList);
299
300                 debugResultList(uuid.getValue(), resultList, idxStart);
301
302             }
303         }
304
305         // Step 2.4: Read other problems from mountpoint
306         if (isNetworkElementCurrentProblemsSupporting12) {
307             idxStart = resultList.size();
308             readNetworkElementCurrentProblems12(resultList);
309             debugResultList("CurrentProblems12", resultList, idxStart);
310         }
311
312         return resultList;
313
314     }
315
316     /**
317      * Get from LayerProtocolExtensions the related generated ONF Interface PAC class which represents it.
318      *
319      * @param lp logical termination point
320      * @return Class of InterfacePac
321      */
322     @Nullable
323     private Class<?> getLpExtension(@Nullable Lp lp) {
324
325         String capability = EMPTY;
326         String revision = EMPTY;
327         String conditionalPackage = EMPTY;
328         Class<?> res = null;
329
330         if (lp != null) {
331             for (Extension e : getExtensionList(lp)) {
332                 if (e.getValueName().contentEquals("capability")) {
333                     capability = e.getValue();
334                     int idx = capability.indexOf("?");
335                     if (idx != -1) {
336                         capability = capability.substring(0, idx);
337                     }
338                 }
339                 if (e.getValueName().contentEquals("revision")) {
340                     revision = e.getValue();
341                 }
342                 if (e.getValueName().contentEquals("conditional-package")) {
343                     conditionalPackage = e.getValue();
344                 }
345             }
346         }
347         // QName qName =
348         // org.opendaylight.yangtools.yang.common.QName.create("urn:onf:params:xml:ns:yang:microwave-model",
349         // "2017-03-24", "mw-air-interface-pac").intern();
350         LOG.info("LpExtension capability={} revision={} conditionalPackage={}", capability, revision,
351                 conditionalPackage);
352         if (!capability.isEmpty() && !revision.isEmpty() && !conditionalPackage.isEmpty()) {
353             try {
354                 QName qName = QName.create(capability, revision, conditionalPackage);
355                 res = this.microwaveModel.getClassForLtpExtension(qName);
356             } catch (IllegalArgumentException e) {
357                 LOG.debug("Can not create QName from ({}{}{}): {}", capability, revision, conditionalPackage,
358                         e.getMessage());
359             }
360         }
361         return res;
362     }
363
364     /**
365      * Read element from class that could be not available
366      *
367      * @param ltp layer termination point
368      * @return List with extension parameters or empty list
369      */
370     @Nonnull
371     private static List<Extension> getExtensionList(@Nullable Lp ltp) {
372         if (ltp != null && ltp.getExtension() != null) {
373             return ltp.getExtension();
374         } else {
375             return EMPTYLTPEXTENSIONLIST;
376         }
377     }
378
379     @Nonnull
380     private List<? extends OtnHistoryDataG> readTheHistoricalPerformanceData(Lp lp) {
381         ONFLayerProtocolName lpName = ONFLayerProtocolName.valueOf(lp.getLayerProtocolName());
382
383         return this.microwaveModel.readTheHistoricalPerformanceData(lpName, lp);
384     }
385
386     @Override
387     public AllPm getHistoricalPM() {
388
389         synchronized (getPmLock()) {
390             if (pmLp != null) {
391                 LOG.debug("Enter query PM");
392                 AllPm allPm = new AllPm();
393                 Lp lp = pmLp;
394
395                 List<? extends OtnHistoryDataG> resultList = readTheHistoricalPerformanceData(lp);
396                 LOG.debug("Got records: {}", resultList.size());
397                 // org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.g._874._1.model.rev170320.GranularityPeriodType
398                 GranularityPeriodType granularityPeriod;
399                 for (OtnHistoryDataG perf : resultList) {
400
401                     granularityPeriod = perf.getGranularityPeriod();
402                     if (granularityPeriod == null) {
403                         granularityPeriod = GranularityPeriodType.Unknown;
404                     }
405
406                     switch (granularityPeriod) {
407                         case Period15Min: {
408                             EsHistoricalPerformance15Minutes pm =
409                                     new EsHistoricalPerformance15Minutes(getMountPointNodeName(), lp)
410                                             .setHistoricalRecord15Minutes(perf);
411                             allPm.add(pm);
412                         }
413                             break;
414
415                         case Period24Hours: {
416                             EsHistoricalPerformance24Hours pm =
417                                     new EsHistoricalPerformance24Hours(getMountPointNodeName(), lp)
418                                             .setHistoricalRecord24Hours(perf);
419                             LOG.debug("Write 24h write to DB");
420                             allPm.add(pm);
421                         }
422                             break;
423
424                         default:
425                             LOG.warn("Unknown granularity {}", perf.getGranularityPeriod());
426                             break;
427
428                     }
429                 }
430                 LOG.debug("Deliver normalized records: {}", allPm.size());
431                 return allPm;
432             } else {
433                 LOG.debug("Deliver empty, no LTP");
434                 return AllPm.getEmpty();
435             }
436         }
437     }
438
439
440     /**
441      * Remove all entries from list
442      */
443     @Override
444     public int removeAllCurrentProblemsOfNode() {
445         return microwaveEventListener.removeAllCurrentProblemsOfNode();
446     }
447
448     /**
449      * Register the listener
450      */
451     @Override
452     public void doRegisterMicrowaveEventListener(MountPoint mountPoint) {
453         LOG.info("End registration listener for Mountpoint {}", mountPoint.getIdentifier().toString());
454         final Optional<NotificationService> optionalNotificationService =
455                 mountPoint.getService(NotificationService.class);
456         final NotificationService notificationService = optionalNotificationService.get();
457         // notificationService.registerNotificationListener(microwaveEventListener);
458         listenerRegistrationresult =
459                 notificationService.registerNotificationListener(microwaveModel.getNotificationListener());
460         LOG.info("End registration listener for Mountpoint {} Listener: {} Result: {}",
461                 mountPoint.getIdentifier().toString(), optionalNotificationService, listenerRegistrationresult);
462     }
463
464
465     /*------------------------------------------------------------
466      * private function to access database
467      */
468
469     /*-----------------------------------------------------------------------------
470      * Reading problems for the networkElement V1.2
471      */
472
473     private List<ProblemNotificationXml> readNetworkElementCurrentProblems12(List<ProblemNotificationXml> resultList) {
474
475         LOG.info("DBRead Get {} NetworkElementCurrentProblems12", getMountPointNodeName());
476
477         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac> networkElementCurrentProblemsIID =
478                 InstanceIdentifier.builder(
479                         org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac.class)
480                         .build();
481
482         // Step 2.3: read to the config data store
483         NetworkElementPac problemPac;
484         NetworkElementCurrentProblems problems;
485         try {
486             problemPac = GenericTransactionUtils.readData(getNetconfNodeDataBroker(), LogicalDatastoreType.OPERATIONAL,
487                     networkElementCurrentProblemsIID);
488             problems = problemPac.getNetworkElementCurrentProblems();
489             if (problems == null) {
490                 LOG.debug("DBRead no NetworkElementCurrentProblems12");
491             } else if (problems.getCurrentProblemList() == null) {
492                 LOG.debug("DBRead empty CurrentProblemList12");
493             } else {
494                 for (org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.network.element.current.problems.g.CurrentProblemList problem : problems
495                         .getCurrentProblemList()) {
496                     resultList.add(new ProblemNotificationXml(getMountPointNodeName(), problem.getObjectReference(),
497                             problem.getProblemName(), InternalSeverity.valueOf(problem.getProblemSeverity()),
498                             problem.getSequenceNumber().toString(),
499                             InternalDateAndTime.valueOf(problem.getTimeStamp())));
500                 }
501             }
502         } catch (Exception e) {
503             LOG.warn("DBRead {} NetworkElementCurrentProblems12 not supported. Message '{}' ", getMountPointNodeName(),
504                     e.getMessage());
505         }
506         return resultList;
507
508     }
509
510     @Override
511     public void close() throws Exception {
512         if (listenerRegistrationresult != null) {
513             listenerRegistrationresult.close();
514         }
515     }
516
517
518
519
520 }