/* * ============LICENSE_START======================================================= * ONAP : ccsdk features * ================================================================================ * Copyright (C) 2020 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.onf14.dom.impl.equipment; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Optional; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.dom.impl.dataprovider.Onf14DomToInternalDataModel; import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.dom.impl.util.Onf14DMDOMUtility; import org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.dom.impl.util.Onf14DevicemanagerQNames; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Onf14DomEquipmentManager { private static final Logger log = LoggerFactory.getLogger(Onf14DomEquipmentManager.class); private static final int EQUIPMENTROOTLEVEL = 0; private final NetconfDomAccessor netconfDomAccessor; private final DataProvider databaseService; private final Onf14DomToInternalDataModel onf14Mapper; private final List equipmentUuidList; public Onf14DomEquipmentManager(NetconfDomAccessor netconfDomAccessor, DataProvider databaseService, Onf14DomToInternalDataModel onf14Mapper) { super(); this.netconfDomAccessor = Objects.requireNonNull(netconfDomAccessor); this.databaseService = Objects.requireNonNull(databaseService); this.onf14Mapper = Objects.requireNonNull(onf14Mapper); this.equipmentUuidList = new ArrayList<>(); } public List getEquipmentUuidList() { return equipmentUuidList; } private List collectEquipment(List list, MapEntryNode currentEq, MapEntryNode parentEq, long treeLevel) { // if the Equipment UUID is already in the list, it was already processed // needed for solving possible circular dependencies if (equipmentUuidList.contains(Onf14DMDOMUtility.getUuidFromEquipment(currentEq))) { log.debug("Not adding equipment with uuid {} because it was aleady added...", Onf14DMDOMUtility.getUuidFromEquipment(currentEq)); return list; } // we add this to our internal list, such that we avoid circular dependencies equipmentUuidList.add(Onf14DMDOMUtility.getUuidFromEquipment(currentEq)); log.debug("Adding equipment with uuid {} to the database...", Onf14DMDOMUtility.getUuidFromEquipment(currentEq)); // we add our current equipment to the database list.add(onf14Mapper.getInternalEquipment(netconfDomAccessor.getNodeId(), currentEq, parentEq, treeLevel)); // we iterate the kids of our current equipment and add them to the database // recursively // the actual reference is here: // /core-model:control-construct/equipment/contained-holder/occupying-fru MapNode containedHolderMap = (MapNode) currentEq .childByArg(new NodeIdentifier(Onf14DevicemanagerQNames.CORE_MODEL_CC_EQPT_CONTAINED_HOLDER)); if (containedHolderMap != null) { Collection containedHolderCollection = containedHolderMap.body(); for (MapEntryNode holder : containedHolderCollection) { String occupyingFru = Onf14DMDOMUtility.getLeafValue(holder, Onf14DevicemanagerQNames.CORE_MODEL_CC_EQPT_OCCUPYING_FRU); if (occupyingFru != null) { Optional childEq = readEquipmentInstance(netconfDomAccessor, occupyingFru); if (childEq.isPresent()) { // current becomes parent and tree level increases by 1 collectEquipment(list, (MapEntryNode) childEq.get(), currentEq, treeLevel + 1); } } } } return list; } // public methods /** * Set all equipment data from controlConstruct into database and into this manager. * * @param controlConstruct with complete device data */ public void setEquipmentData(NormalizedNode controlConstruct) { Objects.requireNonNull(controlConstruct); // the top-level-equipment list contains the root objects of the Equipment Model log.debug("Getting list of topLevelEquipment for mountpoint {}", netconfDomAccessor.getNodeId()); // adding all root Equipment objects to the DB List inventoryList = new ArrayList<>(); for (String uuid : getTopLevelEquipment(controlConstruct)) { Optional equipment = readEquipmentInstance(netconfDomAccessor, uuid); MapEntryNode equipmentEntry = (MapEntryNode) equipment.get(); if (equipmentEntry != null) { collectEquipment(inventoryList, equipmentEntry, null, EQUIPMENTROOTLEVEL); } } this.databaseService.writeInventory(netconfDomAccessor.getNodeId().getValue(), inventoryList); } private List getTopLevelEquipment(NormalizedNode transformedInput) { List topLvlEqptList = new ArrayList<>(); Collection topLevelEqptListColl = (Collection) transformedInput.body(); Iterator childEntryItr = topLevelEqptListColl.iterator(); while (childEntryItr.hasNext()) { LeafSetEntryNode childEntryNode = (LeafSetEntryNode) childEntryItr.next(); topLvlEqptList.add((String) childEntryNode.body()); } return topLvlEqptList; } /** * @param accessData to access device * @param equipmentUuid uuid of equipment to be read * @return Optional Equipment */ private Optional readEquipmentInstance(NetconfDomAccessor accessData, String equipmentUuid) { log.info("DBRead Get equipment from mountpoint {} for uuid {}", accessData.getNodeId().getValue(), equipmentUuid); InstanceIdentifierBuilder equipmentIIDBuilder = YangInstanceIdentifier.builder() .node(Onf14DevicemanagerQNames.CORE_MODEL_CONTROL_CONSTRUCT_CONTAINER) .node(Onf14DevicemanagerQNames.CORE_MODEL_CC_EQPT) .nodeWithKey(Onf14DevicemanagerQNames.CORE_MODEL_CC_EQPT, QName.create(Onf14DevicemanagerQNames.CORE_MODEL_CC_EQPT, "uuid").intern(), equipmentUuid); return accessData.readDataNode(LogicalDatastoreType.CONFIGURATION, equipmentIIDBuilder.build()); } }