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