2  * ============LICENSE_START=======================================================
 
   3  * ONAP : ccsdk features
 
   4  * ================================================================================
 
   5  * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property.
 
   7  * ================================================================================
 
   8  * Licensed under the Apache License, Version 2.0 (the "License");
 
   9  * you may not use this file except in compliance with the License.
 
  10  * You may obtain a copy of the License at
 
  12  *     http://www.apache.org/licenses/LICENSE-2.0
 
  14  * Unless required by applicable law or agreed to in writing, software
 
  15  * distributed under the License is distributed on an "AS IS" BASIS,
 
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  17  * See the License for the specific language governing permissions and
 
  18  * limitations under the License.
 
  19  * ============LICENSE_END=========================================================
 
  22 package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.dataprovider;
 
  24 import java.time.Instant;
 
  25 import java.util.ArrayList;
 
  26 import java.util.Collection;
 
  27 import java.util.Date;
 
  28 import java.util.List;
 
  29 import java.util.Objects;
 
  30 import java.util.Optional;
 
  31 import java.util.regex.Matcher;
 
  32 import java.util.regex.Pattern;
 
  33 import org.eclipse.jdt.annotation.NonNull;
 
  34 import org.eclipse.jdt.annotation.Nullable;
 
  35 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp;
 
  36 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl;
 
  37 import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.util.ORanDMDOMUtility;
 
  38 import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.util.ORanDeviceManagerQNames;
 
  39 import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.yangspecs.ORANFM;
 
  40 import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.yangspecs.OnapSystem;
 
  41 import org.opendaylight.mdsal.dom.api.DOMEvent;
 
  42 import org.opendaylight.mdsal.dom.api.DOMNotification;
 
  43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 
  44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
 
  45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder;
 
  46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity;
 
  47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough;
 
  48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder;
 
  49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
 
  50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder;
 
  51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType;
 
  52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType;
 
  53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 
  54 import org.opendaylight.yangtools.yang.binding.CodeHelpers;
 
  55 import org.opendaylight.yangtools.yang.common.Uint32;
 
  56 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 
  57 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 
  58 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 
  59 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 
  60 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 
  61 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
  62 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
 
  63 import org.slf4j.Logger;
 
  64 import org.slf4j.LoggerFactory;
 
  66 public class ORanDOMToInternalDataModel {
 
  68     private static final Logger LOG = LoggerFactory.getLogger(ORanDOMToInternalDataModel.class);
 
  69     private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter();
 
  71     public static List<Inventory> getInventoryList(NodeId nodeId, NormalizedNode hwData) {
 
  73         List<Inventory> inventoryResultList = new ArrayList<Inventory>();
 
  74         ContainerNode hwContainer = (ContainerNode) hwData;
 
  75         MapNode componentMap = (MapNode) hwContainer
 
  76                 .getChildByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST));
 
  77         Collection<MapEntryNode> componentMapEntries = componentMap.body();
 
  79         for (MapEntryNode componentMapEntryNode : getRootComponents(componentMapEntries)) {
 
  81                     recurseGetInventory(nodeId, componentMapEntryNode, componentMapEntries, 0, inventoryResultList);
 
  83         // Verify if result is complete
 
  84         if (componentMapEntries.size() != inventoryResultList.size()) {
 
  86                     "Not all data were written to the Inventory. Potential entries with missing "
 
  87                             + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}",
 
  88                     nodeId.getValue(), componentMapEntries.size(), inventoryResultList.size());
 
  90         return inventoryResultList;
 
  93     private static List<Inventory> recurseGetInventory(NodeId nodeId, MapEntryNode component,
 
  94             Collection<MapEntryNode> componentList, int treeLevel, List<Inventory> inventoryResultList) {
 
  95         //Add element to list, if conversion successfull
 
  96         Optional<Inventory> oInventory = getInternalEquipment(nodeId, component, treeLevel);
 
  97         if (oInventory.isPresent()) {
 
  98             inventoryResultList.add(oInventory.get());
 
 100         //Walk through list of child keys and add to list
 
 101         for (String childUuid : CodeHelpers.nonnull(new ArrayList<>(ORanDMDOMUtility.getLeafListValue(component,
 
 102                 ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CONTAINS_CHILD)))) {
 
 103             for (MapEntryNode c : getComponentsByName(childUuid, componentList)) {
 
 104                 inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList);
 
 107         return inventoryResultList;
 
 110     public static List<MapEntryNode> getRootComponents(Collection<MapEntryNode> componentMapEntries) {
 
 111         List<MapEntryNode> resultList = new ArrayList<>();
 
 112         for (MapEntryNode componentMapEntryNode : componentMapEntries) {
 
 113             if (ORanDMDOMUtility.getLeafValue(componentMapEntryNode,
 
 114                     ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_PARENT) == null) { // Root elements do not have a parent
 
 115                 resultList.add(componentMapEntryNode);
 
 121     private static List<MapEntryNode> getComponentsByName(String name, Collection<MapEntryNode> componentList) {
 
 122         List<MapEntryNode> resultList = new ArrayList<>();
 
 123         for (MapEntryNode c : componentList) {
 
 124             if (name.equals(ORanDMDOMUtility.getKeyValue(c))) { // <-- Component list is flat search for child's of name
 
 131     public static Optional<Inventory> getInternalEquipment(NodeId nodeId, MapEntryNode component, int treeLevel) {
 
 133         // Make sure that expected data are not null
 
 134         Objects.requireNonNull(nodeId);
 
 135         Objects.requireNonNull(component);
 
 137         // Read mandatory data
 
 140         String nodeIdString = nodeId.getValue();
 
 142         String uuid = ORanDMDOMUtility.getKeyValue(component);
 
 145                 ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_PARENT);
 
 147         String uuidParent = idParent != null ? idParent : uuid; //<- Passt nicht
 
 149         // do consistency check if all mandatory parameters are there
 
 150         if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) {
 
 153             InventoryBuilder inventoryBuilder = new InventoryBuilder();
 
 155             // General assumed as mandatory
 
 156             inventoryBuilder.setNodeId(nodeIdString);
 
 157             inventoryBuilder.setUuid(uuid);
 
 158             inventoryBuilder.setParentUuid(uuidParent);
 
 159             inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel));
 
 161             // -- String list with ids of holders (optional)
 
 162             inventoryBuilder.setContainedHolder(ORanDMDOMUtility.getLeafListValue(component,
 
 163                     ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CONTAINS_CHILD));
 
 165             // -- Manufacturer related things (optional)
 
 168                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME);
 
 169             inventoryBuilder.setManufacturerName(mfgName);
 
 170             inventoryBuilder.setManufacturerIdentifier(mfgName);
 
 172             // Equipment type (optional)
 
 173             inventoryBuilder.setDescription(
 
 174                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_DESC));
 
 175             inventoryBuilder.setModelIdentifier(ORanDMDOMUtility.getLeafValue(component,
 
 176                     ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MODEL_NAME));
 
 178             inventoryBuilder.setPartTypeId(
 
 179                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CLASS));
 
 181             inventoryBuilder.setTypeName(ORanDMDOMUtility.getKeyValue(component));
 
 182             inventoryBuilder.setVersion(
 
 183                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_HW_REV));
 
 185             // Equipment instance (optional)
 
 188                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_DATE);
 
 189             if (mfgDate != null) {
 
 190                 inventoryBuilder.setDate(mfgDate);
 
 192             inventoryBuilder.setSerial(
 
 193                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_SER_NUM));
 
 195             return Optional.of(inventoryBuilder.build());
 
 197         return Optional.empty();
 
 201      * If system data is available convert
 
 206     public static Optional<Guicutthrough> getGuicutthrough(@Nullable AugmentationNode onapSysAugData,  @NonNull OnapSystem onapSys) {
 
 208         if (onapSysAugData != null) {
 
 209             String name = ORanDMDOMUtility.getLeafValue(onapSysAugData, onapSys.getName());
 
 211             Uri uri = new Uri(ORanDMDOMUtility.getLeafValue(onapSysAugData, onapSys.getWebUi()));
 
 212             if (uri.getValue() != null) {
 
 213                 GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder();
 
 215                     gcBuilder.setName(name);
 
 217                 gcBuilder.setWeburi(uri.getValue());
 
 218                 return Optional.of(gcBuilder.build());
 
 220             LOG.warn("Uri not set to invoke a Gui cut through session to the device. Please set the Uri in the device");
 
 222         LOG.warn("Retrieving augmented System details failed. Gui cut through information not available");
 
 223         return Optional.empty();
 
 227      * Convert fault notification into data-provider FaultLogEntity
 
 229      * @param notification with O-RAN notification
 
 231      * @param nodeId of node to handle
 
 232      * @param counter to be integrated into data
 
 233      * @return FaultlogEntity with data
 
 235     public static FaultlogEntity getFaultLog(DOMNotification notification, @NonNull ORANFM oranfm, NodeId nodeId, Integer counter) {
 
 236         ContainerNode cn = notification.getBody();
 
 237         FaultlogBuilder faultAlarm = new FaultlogBuilder();
 
 238         faultAlarm.setNodeId(nodeId.getValue());
 
 239         faultAlarm.setObjectId(ORanDMDOMUtility.getLeafValue(cn, oranfm.getFaultSourceQName()));
 
 240         faultAlarm.setProblem(ORanDMDOMUtility.getLeafValue(cn, oranfm.getFaultTextQName()));
 
 241         faultAlarm.setSeverity(getSeverityType(
 
 242                 ORanDMDOMUtility.getLeafValue(cn, oranfm.getFaultSeverityQName()),
 
 243                 ORanDMDOMUtility.getLeafValue(cn, oranfm.getFaultIsClearedQName()).equals("true")));
 
 244         faultAlarm.setCounter(counter);
 
 245         faultAlarm.setId(ORanDMDOMUtility.getLeafValue(cn, oranfm.getFaultIdQName()));
 
 246         faultAlarm.setSourceType(SourceType.Netconf);
 
 247         faultAlarm.setTimestamp(getEventTime(notification));
 
 248         return faultAlarm.build();
 
 251     public static FaultlogEntity getFaultLog(UnkeyedListEntryNode activeAlarmEntry, ORANFM oranfm, NodeId nodeId, Integer counter) {
 
 252         FaultlogBuilder faultAlarm = new FaultlogBuilder();
 
 253         faultAlarm.setNodeId(nodeId.getValue());
 
 254         faultAlarm.setObjectId(getObjectId(
 
 255                 ORanDMDOMUtility.getLeafValue(activeAlarmEntry, oranfm.getFaultSourceQName())));
 
 256         faultAlarm.setProblem(
 
 257                 ORanDMDOMUtility.getLeafValue(activeAlarmEntry, oranfm.getFaultTextQName()));
 
 258         faultAlarm.setSeverity(getSeverityType(
 
 259                 ORanDMDOMUtility.getLeafValue(activeAlarmEntry, oranfm.getFaultSeverityQName()),
 
 260                 ORanDMDOMUtility.getLeafValue(activeAlarmEntry, oranfm.getFaultIsClearedQName())
 
 262         faultAlarm.setCounter(counter);
 
 263         faultAlarm.setId(ORanDMDOMUtility.getLeafValue(activeAlarmEntry, oranfm.getFaultIdQName()));
 
 264         faultAlarm.setSourceType(SourceType.Netconf);
 
 265         faultAlarm.setTimestamp(NetconfTimeStampImpl.getConverter().getTimeStamp(
 
 266                 ORanDMDOMUtility.getLeafValue(activeAlarmEntry, oranfm.getFaultEventTimeQName())));
 
 267         return faultAlarm.build();
 
 272      * Convert Instant to NETCONF DateAndTime
 
 273      * @param eventTimeInstant
 
 274      * @return DateAndTime
 
 276     public static DateAndTime getDateAndTimeOfInstant(Instant eventTimeInstant) {
 
 277         Date eventDate = Date.from(eventTimeInstant);
 
 278         return new DateAndTime(NETCONFTIME_CONVERTER.getTimeStamp(eventDate));
 
 281     private static DateAndTime getEventTime(DOMNotification notification) {
 
 282         DateAndTime eventTime;
 
 283         Instant notificationEventTime = null;
 
 284         if (notification instanceof DOMEvent) {
 
 285             notificationEventTime = ((DOMEvent) notification).getEventInstant();
 
 286             eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp(notificationEventTime.toString());
 
 288             eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp();
 
 294      * Convert O-RAN specific severity into data-provider severity
 
 296      * @param faultSeverity O-RAN severity
 
 297      * @param isCleared clear indicator
 
 298      * @return data-provider severity type
 
 299      * @throws IllegalArgumentException if conversion not possible.
 
 301     private static SeverityType getSeverityType(@Nullable String faultSeverity, @Nullable Boolean isCleared)
 
 302             throws IllegalArgumentException {
 
 303         if (isCleared != null && isCleared) {
 
 304             return SeverityType.NonAlarmed;
 
 306         if (faultSeverity != null) {
 
 307             switch (faultSeverity) {
 
 309                     return SeverityType.Critical;
 
 311                     return SeverityType.Major;
 
 313                     return SeverityType.Minor;
 
 315                     return SeverityType.Warning;
 
 318         throw new IllegalArgumentException("Unknown Alarm state represent as Critical. isCleared=" + isCleared
 
 319                 + " faultSeverity=" + faultSeverity);
 
 322     private static String getObjectId(String leafValue) {
 
 323         // fault-source = /ietf-hardware:hardware/component[name='slot0-logical0']
 
 324         Pattern p = Pattern.compile("\\/ietf-hardware:hardware\\/component\\[name=\\'(.*)\\']");
 
 325         Matcher m = p.matcher(leafValue);