b157ae4b59153e281e95eaf23bd1c9dbb7f11e6a
[ccsdk/features.git] / sdnr / wt / devicemanager-o-ran-sc / o-ran / ru-fh / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / oran / impl / dom / ORanDOMToInternalDataModel.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
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
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom;
23
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 org.eclipse.jdt.annotation.Nullable;
32 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp;
33 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl;
34 import org.opendaylight.mdsal.dom.api.DOMEvent;
35 import org.opendaylight.mdsal.dom.api.DOMNotification;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
47 import org.opendaylight.yangtools.yang.binding.CodeHelpers;
48 import org.opendaylight.yangtools.yang.common.Uint32;
49 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
50 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
51 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
52 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
53 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
54 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 public class ORanDOMToInternalDataModel {
59
60     private static final Logger LOG = LoggerFactory.getLogger(ORanDOMToInternalDataModel.class);
61     private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter();
62
63     public static List<Inventory> getInventoryList(NodeId nodeId, NormalizedNode hwData) {
64
65         List<Inventory> inventoryResultList = new ArrayList<Inventory>();
66         ContainerNode hwContainer = (ContainerNode) hwData;
67         MapNode componentMap = (MapNode) hwContainer
68                 .getChildByArg(new NodeIdentifier(ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST));
69         Collection<MapEntryNode> componentMapEntries = componentMap.body();
70
71         for (MapEntryNode componentMapEntryNode : getRootComponents(componentMapEntries)) {
72             inventoryResultList =
73                     recurseGetInventory(nodeId, componentMapEntryNode, componentMapEntries, 0, inventoryResultList);
74         }
75         // Verify if result is complete
76         if (componentMapEntries.size() != inventoryResultList.size()) {
77             LOG.warn(
78                     "Not all data were written to the Inventory. Potential entries with missing "
79                             + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}",
80                     nodeId.getValue(), componentMapEntries.size(), inventoryResultList.size());
81         }
82         return inventoryResultList;
83     }
84
85     private static List<Inventory> recurseGetInventory(NodeId nodeId, MapEntryNode component,
86             Collection<MapEntryNode> componentList, int treeLevel, List<Inventory> inventoryResultList) {
87         //Add element to list, if conversion successfull
88         Optional<Inventory> oInventory = getInternalEquipment(nodeId, component, treeLevel);
89         if (oInventory.isPresent()) {
90             inventoryResultList.add(oInventory.get());
91         }
92         //Walk through list of child keys and add to list
93         for (String childUuid : CodeHelpers.nonnull(ORanDMDOMUtility.getLeafListValue(component,
94                 ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CONTAINS_CHILD))) {
95             for (MapEntryNode c : getComponentsByName(childUuid, componentList)) {
96                 inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList);
97             }
98         }
99         return inventoryResultList;
100     }
101
102     public static List<MapEntryNode> getRootComponents(Collection<MapEntryNode> componentMapEntries) {
103         List<MapEntryNode> resultList = new ArrayList<>();
104         for (MapEntryNode componentMapEntryNode : componentMapEntries) {
105             if (ORanDMDOMUtility.getLeafValue(componentMapEntryNode,
106                     ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_PARENT) == null) { // Root elements do not have a parent
107                 resultList.add(componentMapEntryNode);
108             }
109         }
110         return resultList;
111     }
112
113     private static List<MapEntryNode> getComponentsByName(String name, Collection<MapEntryNode> componentList) {
114         List<MapEntryNode> resultList = new ArrayList<>();
115         for (MapEntryNode c : componentList) {
116             if (name.equals(ORanDMDOMUtility.getKeyValue(c))) { // <-- Component list is flat search for child's of name
117                 resultList.add(c);
118             }
119         }
120         return resultList;
121     }
122
123     public static Optional<Inventory> getInternalEquipment(NodeId nodeId, MapEntryNode component, int treeLevel) {
124
125         // Make sure that expected data are not null
126         Objects.requireNonNull(nodeId);
127         Objects.requireNonNull(component);
128
129         // Read mandatory data
130
131         @Nullable
132         String nodeIdString = nodeId.getValue();
133         @Nullable
134         String uuid = ORanDMDOMUtility.getKeyValue(component);
135         @Nullable
136         String idParent =
137                 ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_PARENT);
138         @Nullable
139         String uuidParent = idParent != null ? idParent : uuid; //<- Passt nicht
140
141         // do consistency check if all mandatory parameters are there
142         if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) {
143             // Build output data
144
145             InventoryBuilder inventoryBuilder = new InventoryBuilder();
146
147             // General assumed as mandatory
148             inventoryBuilder.setNodeId(nodeIdString);
149             inventoryBuilder.setUuid(uuid);
150             inventoryBuilder.setParentUuid(uuidParent);
151             inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel));
152
153             // -- String list with ids of holders (optional)
154             inventoryBuilder.setContainedHolder(ORanDMDOMUtility.getLeafListValue(component,
155                     ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CONTAINS_CHILD));
156
157             // -- Manufacturer related things (optional)
158             @Nullable
159             String mfgName =
160                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_NAME);
161             inventoryBuilder.setManufacturerName(mfgName);
162             inventoryBuilder.setManufacturerIdentifier(mfgName);
163
164             // Equipment type (optional)
165             inventoryBuilder.setDescription(
166                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_DESC));
167             inventoryBuilder.setModelIdentifier(ORanDMDOMUtility.getLeafValue(component,
168                     ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MODEL_NAME));
169
170             inventoryBuilder.setPartTypeId(
171                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_CLASS));
172
173             inventoryBuilder.setTypeName(ORanDMDOMUtility.getKeyValue(component));
174             inventoryBuilder.setVersion(
175                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_HW_REV));
176
177             // Equipment instance (optional)
178             @Nullable
179             String mfgDate =
180                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_MFG_DATE);
181             if (mfgDate != null) {
182                 inventoryBuilder.setDate(mfgDate);
183             }
184             inventoryBuilder.setSerial(
185                     ORanDMDOMUtility.getLeafValue(component, ORanDeviceManagerQNames.IETF_HW_COMPONENT_LIST_SER_NUM));
186
187             return Optional.of(inventoryBuilder.build());
188         }
189         return Optional.empty();
190     }
191
192     /**
193      * If system data is available convert
194      *
195      * @param sys
196      * @return
197      */
198     public static Optional<Guicutthrough> getGuicutthrough(@Nullable NormalizedNode sys) {
199         AugmentationNode onapSys = (AugmentationNode) sys;
200         if (onapSys != null) {
201             String name = ORanDMDOMUtility.getLeafValue(onapSys, ORanDeviceManagerQNames.ONAP_SYSTEM_NAME);
202             @Nullable
203             Uri uri = new Uri(ORanDMDOMUtility.getLeafValue(onapSys, ORanDeviceManagerQNames.ONAP_SYSTEM_WEB_UI));
204             if (uri.getValue() != null) {
205                 GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder();
206                 if (name != null) {
207                     gcBuilder.setName(name);
208                 }
209                 gcBuilder.setWeburi(uri.getValue());
210                 return Optional.of(gcBuilder.build());
211             }
212             LOG.warn("Uri not set to invoke a Gui cut through session to the device. Please set the Uri in the device");
213         }
214         LOG.warn("Retrieving augmented System details failed. Gui cut through information not available");
215         return Optional.empty();
216     }
217
218     /**
219      * Convert fault notification into data-provider FaultLogEntity
220      *
221      * @param notification with O-RAN notification
222      * @param nodeId of node to handle
223      * @param counter to be integrated into data
224      * @return FaultlogEntity with data
225      */
226     public static FaultlogEntity getFaultLog(DOMNotification notification, NodeId nodeId, Integer counter) {
227         ContainerNode cn = notification.getBody();
228         FaultlogBuilder faultAlarm = new FaultlogBuilder();
229         faultAlarm.setNodeId(nodeId.getValue());
230         faultAlarm.setObjectId(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_SOURCE));
231         faultAlarm.setProblem(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_TEXT));
232         faultAlarm.setSeverity(getSeverityType(
233                 ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_SEVERITY),
234                 ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_IS_CLEARED).equals("true")));
235         faultAlarm.setCounter(counter);
236         faultAlarm.setId(ORanDMDOMUtility.getLeafValue(cn, ORanDeviceManagerQNames.ORAN_FM_FAULT_ID));
237         faultAlarm.setSourceType(SourceType.Netconf);
238         faultAlarm.setTimestamp(getEventTime(notification));
239         return faultAlarm.build();
240     }
241
242     public static DateAndTime getEventTime(DOMNotification notification) {
243         DateAndTime eventTime;
244         Instant notificationEventTime = null;
245         if (notification instanceof DOMEvent) {
246             notificationEventTime = ((DOMEvent) notification).getEventInstant();
247             eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp(notificationEventTime.toString());
248         } else {
249             eventTime = NetconfTimeStampImpl.getConverter().getTimeStamp();
250         }
251         return eventTime;
252     }
253
254     /**
255      * Convert O-RAN specific severity into data-provider severity
256      *
257      * @param faultSeverity O-RAN severity
258      * @param isCleared clear indicator
259      * @return data-provider severity type
260      * @throws IllegalArgumentException if conversion not possible.
261      */
262     public static SeverityType getSeverityType(@Nullable String faultSeverity, @Nullable Boolean isCleared)
263             throws IllegalArgumentException {
264         if (isCleared != null && isCleared) {
265             return SeverityType.NonAlarmed;
266         }
267         if (faultSeverity != null) {
268             switch (faultSeverity) {
269                 case "CRITICAL":
270                     return SeverityType.Critical;
271                 case "MAJOR":
272                     return SeverityType.Major;
273                 case "MINOR":
274                     return SeverityType.Minor;
275                 case "WARNING":
276                     return SeverityType.Warning;
277             }
278         }
279         throw new IllegalArgumentException("Unknown Alarm state represent as Critical. isCleared=" + isCleared
280                 + " faultSeverity=" + faultSeverity);
281     }
282
283     /**
284      * Convert Instant to NETCONF DataAndTime
285      * @param eventTimeInstant
286      * @return DateAndTime
287      */
288     public static DateAndTime getDateAndTimeOfInstant(Instant eventTimeInstant) {
289         Date eventDate = Date.from(eventTimeInstant);
290         return new DateAndTime(NETCONFTIME_CONVERTER.getTimeStamp(eventDate));
291     }
292
293 }