092ad4a8f91158ac5ce402255b85d41af3bb489e
[ccsdk/features.git] / sdnr / wt / devicemanager-onap / onf14 / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / onf14 / 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.impl.equipment;
23
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Objects;
30 import java.util.Optional;
31 import java.util.stream.Collectors;
32 import org.eclipse.jdt.annotation.NonNull;
33 import org.eclipse.jdt.annotation.Nullable;
34 import org.onap.ccsdk.features.sdnr.wt.common.YangHelper;
35 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
36 import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.impl.dataprovider.Onf14ToInternalDataModel;
37 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor;
38 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
39 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
40 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.ControlConstruct;
41 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.UniversalId;
42 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.control.construct.Equipment;
43 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.control.construct.EquipmentKey;
44 import org.opendaylight.yang.gen.v1.urn.onf.yang.core.model._1._4.rev191127.equipment.ContainedHolder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
46 import org.opendaylight.yangtools.util.UnmodifiableCollection;
47 import org.opendaylight.yangtools.yang.binding.CodeHelpers;
48 import org.opendaylight.yangtools.yang.binding.DataObject;
49 import org.opendaylight.yangtools.yang.common.QName;
50 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
51 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
52 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
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 Onf14DomEquipmentManager {
59
60
61     // constants
62     private static final Logger log = LoggerFactory.getLogger(Onf14DomEquipmentManager.class);
63     private static final int EQUIPMENTROOTLEVEL = 0;
64     // end of constants
65
66     // variables
67     private final NetconfDomAccessor netconfDomAccessor;
68     private final DataProvider databaseService;
69     private final Onf14ToInternalDataModel onf14Mapper;
70     // for storing the Equipment UUIDs that are inserted in the DB
71     private final List<UniversalId> equipmentUuidList;
72     // end of variables
73     private final BindingNormalizedNodeSerializer serializer;
74
75     // constructors
76     public Onf14DomEquipmentManager(NetconfDomAccessor netconfDomAccessor, DataProvider databaseService,
77             Onf14ToInternalDataModel onf14Mapper) {
78         super();
79         this.netconfDomAccessor = Objects.requireNonNull(netconfDomAccessor);
80         this.databaseService = Objects.requireNonNull(databaseService);
81         this.onf14Mapper = Objects.requireNonNull(onf14Mapper);
82         this.serializer = Objects.requireNonNull(netconfDomAccessor.getBindingNormalizedNodeSerializer());
83
84         this.equipmentUuidList = new ArrayList<>();
85     }
86     // end of constructors
87
88     // getters and setters
89     public List<UniversalId> getEquipmentUuidList() {
90         return equipmentUuidList;
91     }
92     // end of getters and setters
93
94     // private methods
95     private List<Inventory> collectEquipment(List<Inventory> list, Equipment currentEq, Equipment parentEq,
96             long treeLevel, Map<EquipmentKey, Equipment> equipmentMap, EquipmentKey equipmentKey) {
97         Objects.requireNonNull(list);
98         if (currentEq == null) {
99             log.info("Ignore empty equipment with key {}", equipmentKey);
100             return list;
101         }
102
103         // if the Equipment UUID is already in the list, it was already processed
104         // needed for solving possible circular dependencies
105         if (equipmentUuidList.contains(currentEq.getUuid())) {
106             log.debug("Not adding equipment with uuid {} because it was aleady added...",
107                     currentEq.getUuid().getValue());
108             return list;
109         }
110
111         // we add this to our internal list, such that we avoid circular dependencies
112         equipmentUuidList.add(currentEq.getUuid());
113         log.debug("Adding equipment with uuid {} to the database...", currentEq.getUuid().getValue());
114
115         // we add our current equipment to the database
116         list.add(onf14Mapper.getInternalEquipment(netconfDomAccessor.getNodeId(), currentEq, parentEq, treeLevel));
117
118         // we iterate the kids of our current equipment and add them to the database recursively
119         // the actual reference is here: /core-model:control-construct/equipment/contained-holder/occupying-fru
120         for (ContainedHolder holder : YangHelper.getCollection(currentEq.nonnullContainedHolder())) {
121             @Nullable
122             UniversalId occupyingFru = holder.getOccupyingFru();
123             if (occupyingFru != null) {
124                 equipmentKey = new EquipmentKey(occupyingFru);
125                 collectEquipment(list, equipmentMap.get(equipmentKey), currentEq, treeLevel + 1, equipmentMap,
126                         equipmentKey);
127             }
128         }
129         return list;
130     }
131     // end of private methods
132
133     // public methods
134     /**
135      * Set all equipment data from controlConstruct into database and into this manager.
136      *
137      * @param controlConstruct with complete device data
138      */
139     public void setEquipmentData(ControlConstruct controlConstruct) {
140         Objects.requireNonNull(controlConstruct);
141
142         // the top-level-equipment list contains the root objects of the Equipment Model
143         log.debug("Getting list of topLevelEquipment for mountpoint {}", netconfDomAccessor.getNodeId());
144         // adding all root Equipment objects to the DB
145         for (UniversalId uuid : CodeHelpers.nonnull(controlConstruct.getTopLevelEquipment())) {
146             log.debug("Got back topLevelEquipment with uuid {}", uuid.getValue());
147             EquipmentKey equipmentKey = new EquipmentKey(uuid);
148
149             // adding all root Equipment objects to the DB
150             Map<EquipmentKey, Equipment> equipmentMap = controlConstruct.nonnullEquipment();
151             // recursively adding the root equipment and all its children into the DB
152             List<Inventory> dbInventory = collectEquipment(new ArrayList<>(), equipmentMap.get(equipmentKey), null,
153                     EQUIPMENTROOTLEVEL, equipmentMap, equipmentKey);
154             this.databaseService.writeInventory(netconfDomAccessor.getNodeId().getValue(), dbInventory);
155         }
156     }
157
158     /**
159      * Experimental see section in {@link #Onf14DomNetworkElement.initialReadFromNetworkElement()}
160      * Read one equipment from device
161      *
162      * @param accessData to access device
163      * @param equipmentUuid uuid of equipment to be read
164      * @return Optional Equipment
165      */
166     public Optional<Equipment> readEquipmentInstance(NetconfDomAccessor accessData, UniversalId equipmentUuid) {
167
168         final Class<?> clazzPac = Equipment.class;
169
170         log.info("DBRead Get equipment for class {} from mountpoint {} for uuid {}", clazzPac.getSimpleName(),
171                 accessData.getNodeId().getValue(), equipmentUuid.getValue());
172
173         InstanceIdentifierBuilder equipmentIIDBuilder =
174                 YangInstanceIdentifier.builder().node(ControlConstruct.QNAME).node(Equipment.QNAME).nodeWithKey(
175                         Equipment.QNAME, QName.create(Equipment.QNAME, "uuid").intern(), equipmentUuid.getValue());
176
177         return accessData.readData(LogicalDatastoreType.CONFIGURATION, equipmentIIDBuilder.build(), Equipment.class);
178     }
179
180     /**
181      * Experimental see section in {@link #Onf14DomNetworkElement.initialReadFromNetworkElement()}
182      * Read one equipment list from device.
183      *
184      * @param accessData to access device
185      * @param equipmentUuid uuid of equipment to be read
186      * @return Optional Equipment
187      */
188     public List<DataObject> readEquipmentList(NetconfDomAccessor accessData) {
189         log.info("DBRead Get equipment-list for mountpoint {} ", accessData.getNodeId().getValue());
190
191         InstanceIdentifierBuilder equipmentIIDBuilder =
192                 YangInstanceIdentifier.builder().node(ControlConstruct.QNAME).node(Equipment.QNAME);
193
194         InstanceIdentifierBuilder equipmentIIDBuilderOnly = YangInstanceIdentifier.builder().node(Equipment.QNAME);
195
196         Optional<NormalizedNode<?, ?>> oData =
197                 accessData.readDataNode(LogicalDatastoreType.CONFIGURATION, equipmentIIDBuilder.build());
198         if (oData.isPresent()) {
199             NormalizedNode<?, ?> data = oData.get();
200
201             log.debug("convertNormalizedNode data identifier: {} data nodetype: {}", data.getIdentifier(),
202                     data.getNodeType());
203             final List<DataObject> mapEntries1 = ((MapNode) data).getValue().stream().map(mapEntryNode -> {
204                 final YangInstanceIdentifier mapEntryPath =
205                         equipmentIIDBuilderOnly.build().node(mapEntryNode.getIdentifier());
206                 return serializer.fromNormalizedNode(mapEntryPath, mapEntryNode).getValue();
207             }).collect(Collectors.toList());
208             return mapEntries1;
209         } else {
210             log.warn("Device does not provide any equipment");
211             return Collections.emptyList();
212         }
213     }
214
215     /**
216      * Experimental see section in {@link #Onf14DomNetworkElement.initialReadFromNetworkElement()}
217      * Read one equipment list from device
218      *
219      * @param accessData to access device
220      * @param equipmentUuid uuid of equipment to be read
221      * @return Optional Equipment
222      */
223     public void readTopLevelEquipment(NetconfDomAccessor accessData) {
224
225         log.info("DBRead Get top-level-equipment for mountpoint {}", accessData.getNodeId().getValue());
226
227         InstanceIdentifierBuilder equipmentIIDBuilder = YangInstanceIdentifier.builder().node(ControlConstruct.QNAME)
228                 .node(QName.create(ControlConstruct.QNAME, "top-level-equipment"));
229
230         Optional<NormalizedNode<?, ?>> oData =
231                 accessData.readDataNode(LogicalDatastoreType.CONFIGURATION, equipmentIIDBuilder.build());
232         log.info("Checking for existence of data");
233         if (oData.isPresent()) {
234             log.info("data exists");
235             NormalizedNode<?, ?> data = oData.get();
236             Object value = data.getValue();
237             log.info("DataNode: {} {}", data.getNodeType(), data.getIdentifier());
238             if (value != null) {
239                 log.info("DataNode value: {} {}", value.getClass().getName(), value);
240                 if (value instanceof UnmodifiableCollection) {
241                     @SuppressWarnings("unchecked")
242                     UnmodifiableCollection<LeafSetEntryNode<String>> topLevelEquipmentCollection =
243                             (UnmodifiableCollection<LeafSetEntryNode<String>>) value;
244                     @NonNull
245                     Iterator<LeafSetEntryNode<String>> it = topLevelEquipmentCollection.iterator();
246                     while (it.hasNext()) {
247                         LeafSetEntryNode<String> topLevelEquipmentUuid = it.next();
248                         if (topLevelEquipmentUuid != null) {
249                             log.info("LeafSetEntryNode: {} {} {}", topLevelEquipmentUuid.getValue(),
250                                     topLevelEquipmentUuid.getNodeType(),
251                                     topLevelEquipmentUuid.getValue().getClass().getName());
252                         }
253                     }
254                 }
255             }
256         }
257     }
258     // end of public methods
259
260     // static methods
261     // end of static methods
262
263     // private classes
264     // end of private classes
265 }