2 * ============LICENSE_START========================================================================
3 * ONAP : ccsdk feature sdnr wt
4 * =================================================================================================
5 * Copyright (C) 2020 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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
16 * ============LICENSE_END==========================================================================
18 package org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.impl;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Optional;
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
26 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement;
27 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService;
28 import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider;
29 import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService;
30 import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.FaultData;
31 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.LAYERPROTOCOLNAMETYPEAIRLAYER;
34 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.LayerProtocol1;
35 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.SEVERITYTYPE;
36 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.SEVERITYTYPECRITICAL;
37 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.SEVERITYTYPEMAJOR;
38 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.SEVERITYTYPEMINOR;
39 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.SEVERITYTYPENONALARMED;
40 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.SEVERITYTYPEWARNING;
41 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.air._interface.current.problems.CurrentProblemList;
42 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.air._interface.lp.spec.AirInterfacePac;
43 import org.opendaylight.yang.gen.v1.urn.onf.yang.air._interface._2._0.rev200121.air._interface.pac.AirInterfaceCurrentProblems;
44 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.ControlConstruct;
45 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.LAYERPROTOCOLNAMETYPE;
46 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.UniversalId;
47 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.control.construct.Equipment;
48 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.control.construct.EquipmentKey;
49 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.control.construct.LogicalTerminationPoint;
50 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.control.construct.LogicalTerminationPointKey;
51 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.equipment.ContainedHolder;
52 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.logical.termination.point.LayerProtocol;
53 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.logical.termination.point.LayerProtocolKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementDeviceType;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
56 import org.opendaylight.yangtools.concepts.ListenerRegistration;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.opendaylight.yangtools.yang.binding.NotificationListener;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
63 * Repesentation of ONF Core model 1.4 device Top level element is "ControlConstruct" (replaces "NetworkElement" of
66 public class Onf14NetworkElement implements NetworkElement {
68 private static final Logger log = LoggerFactory.getLogger(Onf14NetworkElement.class);
70 protected static final InstanceIdentifier<ControlConstruct> CONTROLCONSTRUCT_IID =
71 InstanceIdentifier.builder(ControlConstruct.class).build();
73 private static final int EQUIPMENTROOTLEVEL = 0;
75 private final NetconfAccessor netconfAccessor;
76 private final DataProvider databaseService;
77 private final Onf14ToInternalDataModel onf14Mapper;
78 private final @NonNull FaultService faultService;
80 // for storing the Equipment UUIDs that are inserted in the DB
81 private final List<String> equipmentUuidList = new ArrayList<String>();
83 // air interface related members
84 private final List<TechnologySpecificPacKeys> airInterfaceList = new ArrayList<TechnologySpecificPacKeys>();
85 private ListenerRegistration<NotificationListener> airInterfaceNotificationListenerHandler;
86 private @NonNull final Onf14AirInterfaceNotificationListener airInterfaceNotificationListener;
88 Onf14NetworkElement(NetconfAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) {
89 log.info("Create {}", Onf14NetworkElement.class.getSimpleName());
90 this.netconfAccessor = netconfAccess;
91 this.databaseService = serviceProvider.getDataProvider();
92 this.faultService = serviceProvider.getFaultService();
93 this.onf14Mapper = new Onf14ToInternalDataModel();
94 this.airInterfaceNotificationListenerHandler = null;
95 airInterfaceNotificationListener = new Onf14AirInterfaceNotificationListener(netconfAccess, serviceProvider);
98 public void initialReadFromNetworkElement() {
100 // reading the inventory (CoreModel 1.4 Equipment Model) and adding it to the DB
103 FaultData resultList = new FaultData();
105 int problems = faultService.removeAllCurrentProblemsOfNode(netconfAccessor.getNodeId());
106 log.debug("Removed all {} problems from database at registration", problems);
108 readAllAirInterfaceCurrentProblems(resultList);
109 log.debug("NETCONF read current problems completed. Got back {} problems.", resultList.size());
111 faultService.initCurrentProblemStatus(netconfAccessor.getNodeId(), resultList);
112 log.debug("DB write current problems completed");
116 public void readAllAirInterfaceCurrentProblems(FaultData resultList) {
118 int idxStart; // Start index for debug messages
120 for (TechnologySpecificPacKeys key : airInterfaceList) {
121 idxStart = resultList.size();
123 readAirInterfaceCurrentProblemForLtp(key.getLtpUuid(), key.getLocalId(), resultList);
124 debugResultList(key.getLtpUuid().getValue(), resultList, idxStart);
129 public void register() {
130 initialReadFromNetworkElement();
131 // Register netconf stream
132 airInterfaceNotificationListenerHandler =
133 netconfAccessor.doRegisterNotificationListener(airInterfaceNotificationListener);
134 netconfAccessor.registerNotificationsStream(NetconfAccessor.DefaultNotificationsStream);
138 public void deregister() {}
142 public NodeId getNodeId() {
143 return netconfAccessor.getNodeId();
147 public <L extends NetworkElementService> Optional<L> getService(Class<L> clazz) {
148 return Optional.empty();
152 public void warmstart() {}
155 public Optional<NetconfAccessor> getAcessor() {
156 return Optional.of(netconfAccessor);
160 public NetworkElementDeviceType getDeviceType() {
161 return NetworkElementDeviceType.Wireless;
164 public static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType mapSeverity(
165 Class<? extends SEVERITYTYPE> severity) {
167 if (severity != null) {
168 if (severity.getTypeName() == SEVERITYTYPECRITICAL.class.getName()) {
169 return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType.Critical;
170 } else if (severity.getTypeName() == SEVERITYTYPEMAJOR.class.getName()) {
171 return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType.Major;
172 } else if (severity.getTypeName() == SEVERITYTYPEMINOR.class.getName()) {
173 return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType.Minor;
174 } else if (severity.getTypeName() == SEVERITYTYPEWARNING.class.getName()) {
175 return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType.Warning;
176 } else if (severity.getTypeName() == SEVERITYTYPENONALARMED.class.getName()) {
177 return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType.NonAlarmed;
181 return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType.NonAlarmed;
184 private void readEquipmentData() {
186 Optional<ControlConstruct> controlConstruct = readControlConstruct(netconfAccessor);
188 if (controlConstruct.isPresent()) {
189 // the top-level-equipment list contains the root objects of the Equipment Model
190 log.debug("Getting list of topLevelEquipment for mountpoint {}", netconfAccessor.getNodeId());
192 List<UniversalId> topLevelEquipment = controlConstruct.get().getTopLevelEquipment();
194 if (topLevelEquipment != null) {
195 for (UniversalId uuid : topLevelEquipment) {
196 log.debug("Got back topLevelEquipment with uuid {}", uuid.getValue());
198 // adding all root Equipment objects to the DB
200 Equipment equipmentInstance = readEquipmentInstance(netconfAccessor, uuid);
201 if (equipmentInstance != null) {
202 // recursively adding the root equipment and all its children into the DB
203 addEquipmentToDb(equipmentInstance, null, EQUIPMENTROOTLEVEL);
209 // storing all the airInterface LTP UUIDs internally, for later usage
210 readAirInterfaceKeys(controlConstruct);
213 private void addEquipmentToDb(Equipment currentEq, Equipment parentEq, long treeLevel) {
215 // if the Equipment UUID is already in the list, it was already processed
216 // needed for solving possible circular dependencies
217 if (equipmentUuidList.contains(currentEq.getUuid().getValue())) {
218 log.debug("Not adding equipment with uuid {} because it was aleady added...",
219 currentEq.getUuid().getValue());
223 // we add this to our internal list, such that we avoid circular dependencies
224 equipmentUuidList.add(currentEq.getUuid().getValue());
225 log.debug("Adding equipment with uuid {} to the database...", currentEq.getUuid().getValue());
227 // we add our current equipment to the database
228 databaseService.writeInventory(
229 onf14Mapper.getInternalEquipment(netconfAccessor.getNodeId(), currentEq, parentEq, treeLevel));
231 // we iterate the kids of our current equipment and add them to the database recursively
232 // the actual reference is here: /core-model:control-construct/equipment/contained-holder/occupying-fru
234 List<ContainedHolder> holderList = currentEq.nonnullContainedHolder();
236 for (ContainedHolder holder : holderList) {
238 UniversalId occupyingFru = holder.getOccupyingFru();
239 if (occupyingFru != null) {
241 Equipment childEq = readEquipmentInstance(netconfAccessor, occupyingFru);
243 if (childEq != null) {
244 // current becomes parent and tree level increases by 1
245 addEquipmentToDb(childEq, currentEq, treeLevel + 1);
251 private void readAirInterfaceKeys(Optional<ControlConstruct> controlConstruct) {
253 if (controlConstruct.isPresent()) {
255 List<LogicalTerminationPoint> ltpList = controlConstruct.get().nonnullLogicalTerminationPoint();
256 log.debug("Iterating the LTP list for node {}", netconfAccessor.getNodeId().getValue());
258 // iterating all the Logical Termination Point list
259 for (LogicalTerminationPoint ltp : ltpList) {
261 List<LayerProtocol> lpList = ltp.nonnullLayerProtocol();
262 // the Layer Protocol list should contain only one item, since we have an 1:1 relationship between the LTP and the LP
263 if (lpList.size() != 1) {
264 log.debug("Layer protocol has no 1:1 relationship with the LTP.");
267 // accessing the LP, which should be only 1
268 LayerProtocol lp = lpList.get(0);
270 Class<? extends LAYERPROTOCOLNAMETYPE> layerProtocolName = lp.getLayerProtocolName();
271 if (layerProtocolName != null) {
272 // it the LTP has an airInterface technology extension, the layer protocol name is air-layer
273 if (layerProtocolName.getTypeName() == LAYERPROTOCOLNAMETYPEAIRLAYER.class.getName()) {
274 TechnologySpecificPacKeys airInterfaceKey =
275 new TechnologySpecificPacKeys(ltp.getUuid(), lp.getLocalId());
276 airInterfaceList.add(airInterfaceKey);
277 log.debug("Adding Ltp with uuid {} and local-id {} to the air-interface list",
278 ltp.getUuid().getValue(), lp.getLocalId());
285 private void readAirInterfaceCurrentProblemForLtp(UniversalId ltpUuid, String localId, FaultData resultList) {
287 final Class<AirInterfacePac> clazzPac = AirInterfacePac.class;
289 log.info("DBRead Get current problems for class {} from mountpoint {} for LTP uuid {} and local-id {}",
290 clazzPac.getSimpleName(), netconfAccessor.getNodeId().getValue(), ltpUuid.getValue(), localId);
292 // constructing the IID needs the augmentation exposed byy the air-interface-2-0 model
293 InstanceIdentifier<AirInterfaceCurrentProblems> airInterfaceCurrentProblem_IID =
294 InstanceIdentifier.builder(ControlConstruct.class)
295 .child(LogicalTerminationPoint.class, new LogicalTerminationPointKey(ltpUuid))
296 .child(LayerProtocol.class, new LayerProtocolKey(localId)).augmentation(LayerProtocol1.class)
297 .child(AirInterfacePac.class).child(AirInterfaceCurrentProblems.class).build();
299 // reading all the current-problems list for this specific LTP and LP
300 AirInterfaceCurrentProblems problems = netconfAccessor.getTransactionUtils().readData(
301 netconfAccessor.getDataBroker(), LogicalDatastoreType.OPERATIONAL, airInterfaceCurrentProblem_IID);
303 if (problems == null) {
304 log.debug("DBRead Id {} no AirInterfaceCurrentProblems", ltpUuid);
305 } else if (problems.getCurrentProblemList() == null) {
306 log.debug("DBRead Id {} empty CurrentProblemList", ltpUuid);
308 for (CurrentProblemList problem : problems.nonnullCurrentProblemList()) {
309 resultList.add(netconfAccessor.getNodeId(), (int) problem.getSequenceNumber(), problem.getTimestamp(),
310 ltpUuid.getValue(), problem.getProblemName(), mapSeverity(problem.getProblemSeverity()));
315 private Optional<ControlConstruct> readControlConstruct(NetconfAccessor netconfAccessor) {
316 return Optional.ofNullable(netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(),
317 LogicalDatastoreType.OPERATIONAL, CONTROLCONSTRUCT_IID));
320 private @Nullable Equipment readEquipmentInstance(NetconfAccessor accessData, UniversalId equipmentUuid) {
322 final Class<?> clazzPac = Equipment.class;
324 log.info("DBRead Get equipment for class {} from mountpoint {} for uuid {}", clazzPac.getSimpleName(),
325 accessData.getNodeId().getValue(), equipmentUuid.getValue());
327 InstanceIdentifier<Equipment> equipmentIID = InstanceIdentifier.builder(ControlConstruct.class)
328 .child(Equipment.class, new EquipmentKey(equipmentUuid)).build();
330 return accessData.getTransactionUtils().readData(accessData.getDataBroker(), LogicalDatastoreType.OPERATIONAL,
334 // defining a structure that can map the LP local-id and its corresponding LTP uuid
335 private class TechnologySpecificPacKeys {
337 private UniversalId ltpUuid;
338 private String localId;
340 public TechnologySpecificPacKeys(UniversalId uuid, String lId) {
345 public UniversalId getLtpUuid() {
349 public String getLocalId() {
353 public void setLtpUuid(UniversalId uuid) {
357 public void setLocalId(String lId) {
364 * LOG the newly added problems of the interface pac
370 private void debugResultList(String uuid, FaultData resultList, int idxStart) {
371 StringBuilder sb = new StringBuilder();
373 for (int t = idxStart; t < resultList.size(); t++) {
376 sb.append(resultList.get(t));
379 log.debug("Found problems {} {}", uuid, sb);