aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/devicemanager-o-ran-sc/o-ran/ru-fh/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/binding/ORanToInternalDataModel.java
blob: 2469e46b710f63370343f6bb49a2d27e4a4f4666 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*
 * ============LICENSE_START========================================================================
 * ONAP : ccsdk feature sdnr wt
 * =================================================================================================
 * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
 * =================================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 * ============LICENSE_END==========================================================================
 */
package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.binding;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.Alarm.FaultSeverity;
import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif;
import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yangtools.yang.binding.CodeHelpers;
import org.opendaylight.yangtools.yang.common.Uint32;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Convert data to data-provider model and perform consistency checks.<br>
 * <b>Component list characteristics:</b><br>
 * <ul>
 * <li>component list is a flat list tree structure specified
 * <li>via "component.getParent()":
 * <ul>
 * <li>If null we have a root element
 * <li>if not null it is a child element with generated child level<br>
 * </ul>
 * </ul>
 * Example of List:<br>
 *
 *
 */
public class ORanToInternalDataModel {

    private static final Logger log = LoggerFactory.getLogger(ORanToInternalDataModel.class);

    public static List<Inventory> getInventoryList(NodeId nodeId, Collection<Component> componentList) {

        List<Inventory> inventoryResultList = new ArrayList<Inventory>();
        for (Component component : getRootComponents(componentList)) {
            inventoryResultList = recurseGetInventory(nodeId, component, componentList, 0, inventoryResultList);
        }
        // Verify if result is complete
        if (componentList.size() != inventoryResultList.size()) {
            log.warn(
                    "Not all data were written to the Inventory. Potential entries with missing "
                            + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}",
                    nodeId.getValue(), componentList.size(), inventoryResultList.size());
        }
        return inventoryResultList;
    }

    private static List<Inventory> recurseGetInventory(NodeId nodeId, Component component,
            Collection<Component> componentList, int treeLevel, List<Inventory> inventoryResultList) {

        //Add element to list, if conversion successfull
        Optional<Inventory> oInventory = getInternalEquipment(nodeId, component, treeLevel);
        if (oInventory.isPresent()) {
            inventoryResultList.add(oInventory.get());
        }
        //Walk trough list of child keys and add to list
        for (String childUuid : CodeHelpers.nonnull(component.getContainsChild())) {
            for (Component c : getComponentsByName(childUuid, componentList)) {
                inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList);
            }
        }
        return inventoryResultList;
    }

    public static List<Component> getRootComponents(Collection<Component> componentList) {
        List<Component> resultList = new ArrayList<>();
        for (Component c : componentList) {
            if (c.getParent() == null) { // Root elements do not have a parent
                resultList.add(c);
            }
        }
        return resultList;
    }

    private static List<Component> getComponentsByName(String name, Collection<Component> componentList) {
        List<Component> resultList = new ArrayList<>();
        for (Component c : componentList) {
            if (name.equals(c.getName())) { // <-- Component list is flat search for child's of name
                resultList.add(c);
            }
        }
        return resultList;
    }

    /**
     * Convert equipment into Inventory. Decide if inventory can by created from content or not. Public for test case.
     *
     * @param nodeId of node (Similar to mountpointId)
     * @param component to handle
     * @param treeLevel of components
     * @return Inventory if possible to be created.
     */
    public static Optional<Inventory> getInternalEquipment(NodeId nodeId, Component component, int treeLevel) {

        // Make sure that expected data are not null
        Objects.requireNonNull(nodeId);
        Objects.requireNonNull(component);

        // Read manadatory data

        @Nullable
        String nodeIdString = nodeId.getValue();
        @Nullable
        String uuid = component.getName();
        @Nullable
        String idParent = component.getParent();
        @Nullable
        String uuidParent = idParent != null ? idParent : uuid; //<- Passt nicht

        // do consistency check if all mandatory parameters are there
        if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) {

            // Build output data

            InventoryBuilder inventoryBuilder = new InventoryBuilder();

            // General assumed as mandatory
            inventoryBuilder.setNodeId(nodeIdString);
            inventoryBuilder.setUuid(uuid);
            inventoryBuilder.setParentUuid(uuidParent);
            inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel));

            // -- String list with ids of holders (optional)
            inventoryBuilder.setContainedHolder(CodeHelpers.nonnull(component.getContainsChild()));

            // -- Manufacturer related things (optional)
            @Nullable
            String mfgName = component.getMfgName();
            inventoryBuilder.setManufacturerName(mfgName);
            inventoryBuilder.setManufacturerIdentifier(mfgName);

            // Equipment type (optional)
            inventoryBuilder.setDescription(component.getDescription());
            inventoryBuilder.setModelIdentifier(component.getModelName());
            @Nullable
            Class<? extends HardwareClass> xmlClass = component.getXmlClass();
            if (xmlClass != null) {
                inventoryBuilder.setPartTypeId(xmlClass.getName());
            }
            inventoryBuilder.setTypeName(component.getName());
            inventoryBuilder.setVersion(component.getHardwareRev());

            // Equipment instance (optional)
            @Nullable
            DateAndTime mfgDate = component.getMfgDate();
            if (mfgDate != null) {
                inventoryBuilder.setDate(mfgDate.getValue());
            }
            inventoryBuilder.setSerial(component.getSerialNum());

            return Optional.of(inventoryBuilder.build());
        }
        return Optional.empty();
    }

    /**
     * If system data is available convert
     *
     * @param sys
     * @return
     */
    public static Optional<Guicutthrough> getGuicutthrough(@Nullable System1 sys) {
        if (sys != null) {
            String name = sys.getName();
            @Nullable
            Uri uri = sys.getWebUi();
            if (uri != null) {
                GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder();
                if (name != null) {
                    gcBuilder.setName(name);
                }
                gcBuilder.setWeburi(uri.getValue());
                return Optional.of(gcBuilder.build());
            }
            log.warn("Uri not set to invoke a Gui cut through session to the device. Please set the Uri in the device");
        }
        log.warn("Retrieving augmented System details failed. Gui cut through information not available");
        return Optional.empty();
    }

    /**
     * Convert netconf time into Instant
     *
     * @param eventTime with netconf time
     * @return Instant with converted time. If not convertable provide Instant.Min
     */
    public static Instant getInstantTime(@Nullable DateAndTime eventTime) {
        return eventTime != null ? Instant.parse(eventTime.getValue()) : Instant.MIN;
    }

    /**
     * Convert fault notification into data-provider FaultLogEntity
     *
     * @param notification with O-RAN notification
     * @param nodeId of node to handle
     * @param counter to be integrated into data
     * @return FaultlogEntity with data
     */
    public static FaultlogEntity getFaultLog(AlarmNotif notification, NodeId nodeId, Integer counter) {
        FaultlogBuilder faultAlarm = new FaultlogBuilder();
        faultAlarm.setNodeId(nodeId.getValue());
        faultAlarm.setObjectId(notification.getFaultSource());
        faultAlarm.setProblem(notification.getFaultText());
        faultAlarm.setSeverity(getSeverityType(notification.getFaultSeverity(), notification.getIsCleared()));
        faultAlarm.setCounter(counter);
        faultAlarm.setId(String.valueOf(notification.getFaultId()));
        faultAlarm.setSourceType(SourceType.Netconf);
        faultAlarm.setTimestamp(notification.getEventTime());
        return faultAlarm.build();
    }

    /**
     * Convert O-RAN specific severity into data-provider severity
     *
     * @param faultSeverity O-RAN severity
     * @param isCleared clear indicator
     * @return data-provider severity type
     * @throws IllegalArgumentException if conversion not possible.
     */
    public static SeverityType getSeverityType(@Nullable FaultSeverity faultSeverity, @Nullable Boolean isCleared)
            throws IllegalArgumentException {
        if (isCleared != null && isCleared) {
            return SeverityType.NonAlarmed;
        }
        if (faultSeverity != null) {
            switch (faultSeverity) {
                case CRITICAL:
                    return SeverityType.Critical;
                case MAJOR:
                    return SeverityType.Major;
                case MINOR:
                    return SeverityType.Minor;
                case WARNING:
                    return SeverityType.Warning;
            }
        }
        throw new IllegalArgumentException("Unknown Alarm state represent as Critical. isCleared=" + isCleared
                + " faultSeverity=" + faultSeverity);
    }

}