Update versions for Quebec release
[ccsdk/features.git] / sdnr / wt / devicemanager-onap / onf14 / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / onf14 / dom / impl / equipment / Onf14DomEquipmentManager.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 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.onf14.dom.impl.equipment;
23
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Objects;
29 import java.util.Optional;
30 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
31 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.dom.impl.dataprovider.Onf14DomToInternalDataModel;
32 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.dom.impl.util.Onf14DMDOMUtility;
33 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.dom.impl.yangspecs.CoreModel14;
34 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor;
35 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
37 import org.opendaylight.yangtools.yang.common.QName;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
39 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
40 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
41 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
44 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public class Onf14DomEquipmentManager {
49
50     private static final Logger log = LoggerFactory.getLogger(Onf14DomEquipmentManager.class);
51     private static final int EQUIPMENTROOTLEVEL = 0;
52
53     private final NetconfDomAccessor netconfDomAccessor;
54     private final DataProvider databaseService;
55     private final Onf14DomToInternalDataModel onf14Mapper;
56     private final List<String> equipmentUuidList;
57     private final CoreModel14 qNames;
58
59     public Onf14DomEquipmentManager(NetconfDomAccessor netconfDomAccessor, DataProvider databaseService,
60             Onf14DomToInternalDataModel onf14Mapper, CoreModel14 qNames) {
61         super();
62         this.netconfDomAccessor = Objects.requireNonNull(netconfDomAccessor);
63         this.databaseService = Objects.requireNonNull(databaseService);
64         this.onf14Mapper = Objects.requireNonNull(onf14Mapper);
65         this.qNames = qNames;
66         this.equipmentUuidList = new ArrayList<>();
67     }
68
69     // public methods
70     public List<String> getEquipmentUuidList() {
71         return equipmentUuidList;
72     }
73
74     /**
75      * Set all equipment data from controlConstruct into database and into this manager.
76      *
77      * @param controlConstruct with complete device data
78      */
79     public void setEquipmentData(NormalizedNode controlConstruct) {
80         Objects.requireNonNull(controlConstruct);
81
82         // the top-level-equipment list contains the root objects of the Equipment Model
83         log.debug("Iterating through the list of topLevelEquipment for mountpoint {}", netconfDomAccessor.getNodeId());
84         // adding all root Equipment objects to the DB
85         List<Inventory> inventoryList = new ArrayList<>();
86         for (String uuid : getTopLevelEquipment(controlConstruct)) {
87             Optional<NormalizedNode> equipment = readEquipmentInstance(netconfDomAccessor, uuid);
88             log.info("Equipment Data is - {}", equipment.get().prettyTree());
89             MapEntryNode equipmentEntry = (MapEntryNode) equipment.get();
90             if (equipmentEntry != null) {
91                 collectEquipment(inventoryList, equipmentEntry, null, EQUIPMENTROOTLEVEL);
92             }
93         }
94         this.databaseService.writeInventory(netconfDomAccessor.getNodeId().getValue(), inventoryList);
95
96     }
97
98     private List<String> getTopLevelEquipment(NormalizedNode transformedInput) {
99         List<String> topLvlEqptList = new ArrayList<>();
100         Collection<?> topLevelEqptListColl = (Collection<?>) transformedInput.body();
101         Iterator<?> childEntryItr = topLevelEqptListColl.iterator();
102         while (childEntryItr.hasNext()) {
103             LeafSetEntryNode<?> childEntryNode = (LeafSetEntryNode<?>) childEntryItr.next();
104             topLvlEqptList.add((String) childEntryNode.body());
105         }
106         return topLvlEqptList;
107     }
108
109     /**
110      * @param accessData to access device
111      * @param equipmentUuid uuid of equipment to be read
112      * @return Optional Equipment
113      */
114     private Optional<NormalizedNode> readEquipmentInstance(NetconfDomAccessor accessData, String equipmentUuid) {
115
116         log.debug("DBRead Get equipment from mountpoint {} for uuid {}", accessData.getNodeId().getValue(),
117                 equipmentUuid);
118
119         InstanceIdentifierBuilder equipmentIIDBuilder =
120                 YangInstanceIdentifier.builder().node(qNames.getQName("control-construct"))
121                         .node(qNames.getQName("equipment")).nodeWithKey(qNames.getQName("equipment"),
122                                 QName.create(qNames.getQName("equipment"), "uuid").intern(), equipmentUuid);
123
124         return accessData.readDataNode(LogicalDatastoreType.CONFIGURATION, equipmentIIDBuilder.build());
125     }
126
127     private List<Inventory> collectEquipment(List<Inventory> list, MapEntryNode currentEq, MapEntryNode parentEq,
128             long treeLevel) {
129
130         // if the Equipment UUID is already in the list, it was already processed
131         // needed for solving possible circular dependencies
132         if (equipmentUuidList.contains(Onf14DMDOMUtility.getUuidFromEquipment(currentEq, qNames.getQName("uuid")))) {
133             log.debug("Not adding equipment with uuid {} because it was aleady added...",
134                     Onf14DMDOMUtility.getUuidFromEquipment(currentEq, qNames.getQName("uuid")));
135             return list;
136         }
137
138         // we add this to our internal list, such that we avoid circular dependencies
139         equipmentUuidList.add(Onf14DMDOMUtility.getUuidFromEquipment(currentEq, qNames.getQName("uuid")));
140         log.debug("Adding equipment with uuid {} to the database...",
141                 Onf14DMDOMUtility.getUuidFromEquipment(currentEq, qNames.getQName("uuid")));
142
143         // we add our current equipment to the database
144         list.add(onf14Mapper.getInternalEquipment(netconfDomAccessor.getNodeId(), currentEq, parentEq, treeLevel,
145                 qNames));
146
147         // we iterate the kids of our current equipment and add them to the database
148         // recursively
149         // the actual reference is here:
150         // /core-model:control-construct/equipment/contained-holder/occupying-fru
151
152         MapNode containedHolderMap =
153                 (MapNode) currentEq.childByArg(new NodeIdentifier(qNames.getQName("contained-holder")));
154         if (containedHolderMap != null) {
155             Collection<MapEntryNode> containedHolderCollection = containedHolderMap.body();
156             for (MapEntryNode holder : containedHolderCollection) {
157                 String occupyingFru = Onf14DMDOMUtility.getLeafValue(holder,
158                         qNames.getQName("occupying-fru")/*Onf14DevicemanagerQNames.CORE_MODEL_CC_EQPT_OCCUPYING_FRU*/);
159
160                 if (occupyingFru != null) {
161                     Optional<NormalizedNode> childEq = readEquipmentInstance(netconfDomAccessor, occupyingFru);
162                     if (childEq.isPresent()) {
163                         // current becomes parent and tree level increases by 1
164                         collectEquipment(list, (MapEntryNode) childEq.get(), currentEq, treeLevel + 1);
165                     }
166                 }
167             }
168         }
169
170         return list;
171     }
172
173 }