0e1a448b52c26c35eb204602f3934821176ecba9
[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.onf.ne;
19
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.concurrent.CopyOnWriteArrayList;
27 import org.eclipse.jdt.annotation.NonNull;
28 import org.eclipse.jdt.annotation.Nullable;
29 import org.onap.ccsdk.features.sdnr.wt.common.YangHelper;
30 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
31 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService;
32 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf.NetworkElementCoreData;
33 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf.ifpac.WrapperPTPModelRev170208;
34 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf.ifpac.equipment.ONFCoreNetworkElement12Equipment;
35 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf.ifpac.microwave.Helper;
36 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf.ifpac.microwave.WrapperMicrowaveModelRev181010;
37 import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider;
38 import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.FaultData;
39 import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.InventoryInformationDcae;
40 import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.PerformanceDataLtp;
41 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor;
42 import org.opendaylight.mdsal.binding.api.MountPoint;
43 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
44 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.NetworkElement;
45 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.UniversalId;
46 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.extension.g.Extension;
47 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.extension.g.ExtensionKey;
48 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.logical.termination.point.g.Lp;
49 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.network.element.Ltp;
50 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac;
51 import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.network.element.pac.NetworkElementCurrentProblems;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60 /**
61  * This class contains the ONF Core model Version 1.2 related functions.<br>
62  * Provides the basic ONF Core Model function.<br>
63  * - initialReadFromNetworkElement is not implemented in child classes.
64  */
65 public abstract class ONFCoreNetworkElement12Base extends ONFCoreNetworkElementBase implements NetworkElementCoreData {
66
67     private static final Logger LOG = LoggerFactory.getLogger(ONFCoreNetworkElement12Base.class);
68
69     protected static final @NonNull List<Extension> EMPTYLTPEXTENSIONLIST = new ArrayList<>();
70
71     protected static final InstanceIdentifier<NetworkElement> NETWORKELEMENT_IID =
72             InstanceIdentifier.builder(NetworkElement.class).build();
73
74
75     /*-----------------------------------------------------------------------------
76      * Class members
77      */
78
79     // Non specific part. Used by all functions.
80     /** interfaceList is used by PM task and should be synchronized */
81     @SuppressWarnings("null")
82     private final @NonNull List<Lp> interfaceList = Collections.synchronizedList(new CopyOnWriteArrayList<>());
83     private Optional<NetworkElement> optionalNe;
84     private final DataProvider databaseService;
85     // Performance monitoring specific part
86     /** Lock for the PM access specific elements that could be null */
87     private final @NonNull Object pmLock = new Object();
88     protected @Nullable Iterator<Lp> interfaceListIterator = null;
89     /** Actual pmLp used during iteration over interfaces */
90     protected @Nullable Lp pmLp = null;
91
92     // Device monitoring specific part
93     /** Lock for the DM access specific elements that could be null */
94     protected final @NonNull Object dmLock = new Object();
95
96     protected final boolean isNetworkElementCurrentProblemsSupporting12;
97
98     protected final ONFCoreNetworkElement12Equipment equipment;
99
100     protected final NodeId nodeId;
101
102     /*---------------------------------------------------------------
103      * Constructor
104      */
105
106     protected ONFCoreNetworkElement12Base(@NonNull NetconfBindingAccessor acessor, @NonNull DeviceManagerServiceProvider serviceProvider) {
107         super(acessor);
108         this.optionalNe = Optional.empty();
109         this.nodeId = getAcessor().get().getNodeId();
110         this.isNetworkElementCurrentProblemsSupporting12 =
111                 acessor.getCapabilites().isSupportingNamespaceAndRevision(NetworkElementPac.QNAME);
112         this.equipment = new ONFCoreNetworkElement12Equipment(acessor, this);
113         this.databaseService = serviceProvider.getDataProvider();
114         WrapperPTPModelRev170208.initSynchronizationExtension(acessor);
115         LOG.debug("support necurrent-problem-list={}", this.isNetworkElementCurrentProblemsSupporting12);
116     }
117
118     /*---------------------------------------------------------------
119      * Getter/ Setter
120      */
121
122     @Override
123     public Optional<NetworkElement> getOptionalNetworkElement() {
124         return optionalNe;
125     }
126
127     List<Lp> getInterfaceList() {
128         return interfaceList;
129     }
130
131     public Object getPmLock() {
132         return pmLock;
133     }
134
135     /*---------------------------------------------------------------
136      * Core model related function
137      */
138
139     /**
140      * Get uuid of Optional NE.
141      *
142      * @return Uuid or EMPTY String if optionNE is not available
143      */
144     protected String getUuId() {
145         return optionalNe.isPresent() ? Helper.nnGetUniversalId(optionalNe.get().getUuid()).getValue() : EMPTY;
146     }
147
148     /**
149      * Read from NetworkElement and verify LTPs have changed. If the NE has changed, update to the new structure. From
150      * initial state it changes also.
151      */
152     protected boolean readNetworkElementAndInterfaces() {
153
154         LOG.debug("Update mountpoint if changed {}", getMountpoint());
155
156         optionalNe = Optional.ofNullable(getGenericTransactionUtils().readData(getDataBroker(),
157                 LogicalDatastoreType.OPERATIONAL, NETWORKELEMENT_IID));
158         synchronized (pmLock) {
159             boolean change = false;
160
161             if (!optionalNe.isPresent()) {
162                 LOG.debug("Unable to read NE data for mountpoint {}", getMountpoint());
163                 if (!interfaceList.isEmpty()) {
164                     interfaceList.clear();
165                     interfaceListIterator = null;
166                     change = true;
167                 }
168
169             } else {
170                 NetworkElement ne = optionalNe.get();
171                 Optional<Guicutthrough> oGuicutthrough = getGuicutthrough(ne);
172                 if (oGuicutthrough.isPresent()) {
173                     databaseService.writeGuiCutThroughData(oGuicutthrough.get(), getAcessor().get().getNodeId().getValue());
174                 }
175                 LOG.debug("Mountpoint '{}' NE-Name '{}'", getMountpoint(), ne.getName());
176                 List<Lp> actualInterfaceList = getLtpList(ne);
177                 if (!interfaceList.equals(actualInterfaceList)) {
178                     LOG.debug("Mountpoint '{}' Update LTP List. Elements {}", getMountpoint(),
179                             actualInterfaceList.size());
180                     interfaceList.clear();
181                     interfaceList.addAll(actualInterfaceList);
182                     interfaceListIterator = null;
183                     change = true;
184                 }
185             }
186             return change;
187         }
188     }
189
190     /**
191      * Get List of UUIDs for conditional packages from Networkelement<br>
192      * Possible interfaces are:<br>
193      * MWPS, LTP(MWPS-TTP), MWAirInterfacePac, MicrowaveModel-ObjectClasses-AirInterface<br>
194      * ETH-CTP,LTP(Client), MW_EthernetContainer_Pac<br>
195      * MWS, LTP(MWS-CTP-xD), MWAirInterfaceDiversityPac, MicrowaveModel-ObjectClasses-AirInterfaceDiversity<br>
196      * MWS, LTP(MWS-TTP), ,MicrowaveModel-ObjectClasses-HybridMwStructure<br>
197      * MWS, LTP(MWS-TTP), ,MicrowaveModel-ObjectClasses-PureEthernetStructure<br>
198      *
199      * @param ne NetworkElement
200      * @return Id List, never null.
201      */
202
203     private static List<Lp> getLtpList(@Nullable NetworkElement ne) {
204
205         List<Lp> res = Collections.synchronizedList(new ArrayList<Lp>());
206
207         if (ne != null) {
208             Collection<Ltp> ltpRefList = YangHelper.getCollection(ne.getLtp());
209             if (ltpRefList == null) {
210                 LOG.debug("DBRead NE-Interfaces: null");
211             } else {
212                 for (Ltp ltRefListE : ltpRefList) {
213                     Collection<Lp> lpList = YangHelper.getCollection(ltRefListE.getLp());
214                     if (lpList == null) {
215                         LOG.debug("DBRead NE-Interfaces Reference List: null");
216                     } else {
217                         for (Lp ltp : lpList) {
218                             res.add(ltp);
219                         }
220                     }
221                 }
222             }
223         } else {
224             LOG.debug("DBRead NE: null");
225         }
226
227         // ---- Debug
228         if (LOG.isDebugEnabled()) {
229             StringBuilder strBuild = new StringBuilder();
230             for (Lp ltp : res) {
231                 if (strBuild.length() > 0) {
232                     strBuild.append(", ");
233                 }
234                 strBuild.append(Helper.nnGetLayerProtocolName(ltp.getLayerProtocolName()).getValue());
235                 strBuild.append(':');
236                 strBuild.append(Helper.nnGetUniversalId(ltp.getUuid()).getValue());
237             }
238             LOG.debug("DBRead NE-Interfaces: {}", strBuild.toString());
239         }
240         // ---- Debug end
241
242         return res;
243     }
244
245     /**
246      * Read current problems of AirInterfaces and EthernetContainer according to NE status into DB
247      *
248      * @return List with all problems
249      */
250     protected FaultData readAllCurrentProblemsOfNode() {
251
252         // Step 2.3: read the existing faults and add to DB
253         FaultData resultList = new FaultData();
254         int idxStart; // Start index for debug messages
255         UniversalId uuid;
256
257         synchronized (pmLock) {
258             for (Lp lp : interfaceList) {
259
260                 idxStart = resultList.size();
261                 uuid = lp.getUuid();
262                 FaultData.debugResultList(LOG, uuid.getValue(), resultList, idxStart);
263
264             }
265         }
266
267         // Step 2.4: Read other problems from mountpoint
268         if (isNetworkElementCurrentProblemsSupporting12) {
269             idxStart = resultList.size();
270             readNetworkElementCurrentProblems12(resultList);
271             FaultData.debugResultList(LOG, "CurrentProblems12", resultList, idxStart);
272         }
273
274         return resultList;
275
276     }
277
278     /**
279      * Reading problems for the networkElement V1.2
280      *
281      * @param resultList to collect the problems
282      * @return resultList with additonal problems
283      */
284     protected FaultData readNetworkElementCurrentProblems12(FaultData resultList) {
285
286         LOG.info("DBRead Get {} NetworkElementCurrentProblems12", getMountpoint());
287
288         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac> networkElementCurrentProblemsIID =
289                 InstanceIdentifier.builder(
290                         org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac.class)
291                         .build();
292
293         // Step 2.3: read to the config data store
294         NetworkElementPac problemPac;
295         NetworkElementCurrentProblems problems = null;
296         try {
297             problemPac = getGenericTransactionUtils().readData(getDataBroker(), LogicalDatastoreType.OPERATIONAL,
298                     networkElementCurrentProblemsIID);
299             if (problemPac != null) {
300                 problems = problemPac.getNetworkElementCurrentProblems();
301             }
302             if (problems == null) {
303                 LOG.debug("DBRead no NetworkElementCurrentProblems12");
304             } else {
305                 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 : YangHelper
306                         .getCollection(problems.nonnullCurrentProblemList())) {
307                     resultList.add(nodeId, problem.getSequenceNumber(), problem.getTimeStamp(),
308                             problem.getObjectReference(), problem.getProblemName(),
309                             WrapperMicrowaveModelRev181010.mapSeverity(problem.getProblemSeverity()));
310                 }
311             }
312         } catch (Exception e) {
313             LOG.warn("DBRead {} NetworkElementCurrentProblems12 not supported. Message '{}' ", getMountpoint(),
314                     e.getMessage());
315         }
316         return resultList;
317     }
318
319     /*---------------------------------------------------------------
320      * Device Monitor
321      */
322
323     @Override
324     public boolean checkIfConnectionToMediatorIsOk() {
325         synchronized (dmLock) {
326             return optionalNe != null;
327         }
328     }
329
330     /*
331      * New implementation to interpret status with empty LTP List as notConnected => return false
332      * 30.10.2018 Since this behavior is very specific and implicit for specific NE Types
333      *     it needs to be activated by extension or configuration. Change to be disabled at the moment
334      */
335     @Override
336     public boolean checkIfConnectionToNeIsOk() {
337         return true;
338     }
339
340     /*---------------------------------------------------------------
341      * Synchronization
342      */
343
344
345     /*---------------------------------------------------------------
346      * Equipment related functions
347      */
348
349     @Override
350     public @NonNull InventoryInformationDcae getInventoryInformation(String layerProtocolFilter) {
351         LOG.debug("request inventory information. filter: {}" + layerProtocolFilter);
352         return this.equipment.getInventoryInformation(getFilteredInterfaceUuidsAsStringList(layerProtocolFilter));
353     }
354
355     @Override
356     public InventoryInformationDcae getInventoryInformation() {
357         return getInventoryInformation(null);
358     }
359
360     protected List<String> getFilteredInterfaceUuidsAsStringList(String layerProtocolFilter) {
361         List<String> uuids = new ArrayList<>();
362
363         LOG.debug("request inventory information. filter: {}" + layerProtocolFilter);
364         if (optionalNe != null) {
365             // uuids
366             for (Lp lp : this.interfaceList) {
367                 if (layerProtocolFilter == null || layerProtocolFilter.isEmpty() || layerProtocolFilter
368                         .equals(Helper.nnGetLayerProtocolName(lp.getLayerProtocolName()).getValue())) {
369                     uuids.add(Helper.nnGetUniversalId(lp.getUuid()).getValue());
370                 }
371             }
372         }
373         LOG.debug("uuids found: {}", uuids);
374         return uuids;
375     }
376
377
378     /*---------------------------------------------------------------
379      * Performancemanagement specific interface
380      */
381
382     @Override
383     public void resetPMIterator() {
384         synchronized (pmLock) {
385             interfaceListIterator = interfaceList.iterator();
386         }
387         LOG.debug("PM reset iterator");
388     }
389
390     @SuppressWarnings("null")
391     @Override
392     public boolean hasNext() {
393         boolean res;
394         synchronized (pmLock) {
395             res = interfaceListIterator != null ? interfaceListIterator.hasNext() : false;
396         }
397         LOG.debug("PM hasNext LTP {}", res);
398         return res;
399     }
400
401     @SuppressWarnings("null")
402     @Override
403     public void next() {
404         synchronized (pmLock) {
405             if (interfaceListIterator == null) {
406                 pmLp = null;
407                 LOG.debug("PM next LTP null");
408             } else {
409                 pmLp = interfaceListIterator.next();
410                 LOG.debug("PM next LTP {}", Helper.nnGetLayerProtocolName(pmLp.getLayerProtocolName()).getValue());
411             }
412         }
413     }
414
415     @SuppressWarnings("null")
416     @Override
417     public String pmStatusToString() {
418         StringBuilder res = new StringBuilder();
419         synchronized (pmLock) {
420             res.append(pmLp == null ? "no interface"
421                     : Helper.nnGetLayerProtocolName(pmLp.getLayerProtocolName()).getValue());
422             for (Lp lp : getInterfaceList()) {
423                 res.append("IF:");
424                 res.append(Helper.nnGetLayerProtocolName(lp.getLayerProtocolName()).getValue());
425                 res.append(" ");
426             }
427         }
428         return res.toString();
429     }
430
431     @Override
432     public void doRegisterEventListener(MountPoint mountPoint) {
433         //Do nothing
434     }
435
436     @SuppressWarnings("unchecked")
437     @Override
438     public <L extends NetworkElementService> Optional<L> getService(Class<L> clazz) {
439         return clazz.isInstance(this) ? Optional.of((L) this) : Optional.empty();
440     }
441
442     @Override
443     public Optional<PerformanceDataLtp> getLtpHistoricalPerformanceData() {
444         return Optional.empty();
445     }
446
447     //Guicutthrough
448     public Optional<Guicutthrough> getGuicutthrough(NetworkElement ne) {
449         Extension extension = ne.nonnullExtension().get(new ExtensionKey("webUri"));
450         if (extension != null) {
451             GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder();
452             gcBuilder.setName(getAcessor().get().getNodeId().getValue());
453             gcBuilder.setWeburi(extension.getValue());
454             return Optional.of(gcBuilder.build());
455         } else {
456             return Optional.empty();
457         }
458     }
459
460 }