2  * ============LICENSE_START=======================================================
 
   3  * ONAP : ccsdk features
 
   4  * ================================================================================
 
   5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
 
   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
 
  12  *     http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  22 package org.onap.ccsdk.features.sdnr.wt.devicemanager.openroadm71.impl;
 
  24 import java.util.ArrayList;
 
  25 import java.util.Collection;
 
  26 import java.util.Hashtable;
 
  27 import java.util.List;
 
  28 import org.eclipse.jdt.annotation.NonNull;
 
  29 import org.onap.ccsdk.features.sdnr.wt.common.YangHelper;
 
  30 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp;
 
  31 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl;
 
  32 import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider;
 
  33 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
 
  34 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor;
 
  35 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 
  36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.OrgOpenroadmDevice;
 
  37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.packs.CircuitPacks;
 
  38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.Interface;
 
  39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.Xponder;
 
  40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.shelf.Slots;
 
  41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.shelves.Shelves;
 
  42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.xponder.XpdrPort;
 
  43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
 
  44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder;
 
  45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
 
  46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.PmdataEntity;
 
  47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType;
 
  48 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 
  49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
  50 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
  51 import org.opendaylight.yangtools.yang.common.Uint32;
 
  52 import org.slf4j.Logger;
 
  53 import org.slf4j.LoggerFactory;
 
  56  * @author Shabnam Sultana
 
  58  *         Creating the openroadm device as an optical network element and writing inventory, fault, pm data to elastic
 
  62 public class OpenroadmNetworkElement extends OpenroadmNetworkElementBase {
 
  65     private final long EQUIPMENTLEVEL_BASE = 0;
 
  66     private static final Logger LOG = LoggerFactory.getLogger(OpenroadmNetworkElement.class);
 
  67     private Hashtable<String, Long> circuitPacksRecord;
 
  68     private Hashtable<String, Long> shelfProvisionedcircuitPacks;
 
  69     private ListenerRegistration<NotificationListener> openRdmListenerRegistrationResult;
 
  70     private @NonNull final OpenroadmChangeNotificationListener openRdmListener;
 
  71     private ListenerRegistration<NotificationListener> opnRdmFaultListenerRegistrationResult;
 
  72     private @NonNull OpenroadmFaultNotificationListener opnRdmFaultListener;
 
  73     private ListenerRegistration<NotificationListener> opnRdmDeviceListenerRegistrationResult;
 
  74     private OpenroadmDeviceChangeNotificationListener opnRdmDeviceListener;
 
  75     private OpenroadmInventoryInput opnRdmInventoryInput;
 
  76     private PmDataBuilderOpenRoadm openRoadmPmData;
 
  77     private InitialDeviceAlarmReader initialAlarmReader;
 
  79     private static final NetconfTimeStamp ncTimeConverter = NetconfTimeStampImpl.getConverter();
 
  80     private int counter = 1;
 
  84     public OpenroadmNetworkElement(NetconfBindingAccessor netconfAccess, DeviceManagerServiceProvider serviceProvider) {
 
  86         super(netconfAccess, serviceProvider);
 
  88         LOG.info("Create {}", OpenroadmNetworkElement.class.getSimpleName());
 
  89         this.openRdmListenerRegistrationResult = null;
 
  90         this.openRdmListener = new OpenroadmChangeNotificationListener(netconfAccessor, databaseService,
 
  91                 serviceProvider.getWebsocketService());
 
  92         this.opnRdmFaultListenerRegistrationResult = null;
 
  93         this.opnRdmFaultListener = new OpenroadmFaultNotificationListener(netconfAccessor, serviceProvider);
 
  94         this.opnRdmDeviceListenerRegistrationResult = null;
 
  95         this.opnRdmDeviceListener = new OpenroadmDeviceChangeNotificationListener(netconfAccessor, databaseService,
 
  96                 serviceProvider.getWebsocketService());
 
  97         this.circuitPacksRecord = new Hashtable<>();
 
  98         this.shelfProvisionedcircuitPacks = new Hashtable<>();
 
  99         this.openRoadmPmData = new PmDataBuilderOpenRoadm(this.netconfAccessor);
 
 100         this.initialAlarmReader = new InitialDeviceAlarmReader(this.netconfAccessor, serviceProvider);
 
 101         LOG.info("NodeId {}", this.netconfAccessor.getNodeId().getValue());
 
 105     // end of constructors
 
 108     public void initialReadFromNetworkElement() {
 
 110         OrgOpenroadmDevice device = readDevice(this.netconfAccessor);
 
 111         this.opnRdmInventoryInput = new OpenroadmInventoryInput(this.netconfAccessor, device);
 
 112         LOG.info("openroadmMapper details{}", this.opnRdmInventoryInput.getClass().getName());
 
 113         List<Inventory> inventoryList = new ArrayList<>();
 
 114         inventoryList.add(this.opnRdmInventoryInput.getInventoryData(Uint32.valueOf(EQUIPMENTLEVEL_BASE)));
 
 115         readShelvesData(inventoryList, device);
 
 116         readXpndrData(inventoryList, device);
 
 117         readCircuitPacketData(inventoryList, device);
 
 118         readInterfaceData(inventoryList, device);
 
 119         this.databaseService.writeInventory(this.netconfAccessor.getNodeId().getValue(), inventoryList);
 
 120         // Writing initial alarms at the time of device registration
 
 121         initialAlarmReader.faultService();
 
 122         //        Writing historical PM data at the time of device registration
 
 123         List<PmdataEntity> pmDataEntity = new ArrayList<>();
 
 124         pmDataEntity = this.openRoadmPmData.buildPmDataEntity(this.openRoadmPmData.getPmData(this.netconfAccessor));
 
 125         if (!pmDataEntity.isEmpty()) {
 
 126             this.databaseService.doWritePerformanceData(pmDataEntity);
 
 127             LOG.info("PmDatEntity is written with size {}", pmDataEntity.size());
 
 128             for (PmdataEntity ent : pmDataEntity) {
 
 129                 LOG.info("GetNode: {}, granPeriod: {}", ent.getNodeName(), ent.getGranularityPeriod().getName());
 
 132             LOG.info("PmDatEntity is empty");
 
 138     public void register() {
 
 139         initialReadFromNetworkElement();
 
 141         this.openRdmListenerRegistrationResult = netconfAccessor.doRegisterNotificationListener(openRdmListener);
 
 142         this.opnRdmFaultListenerRegistrationResult =
 
 143                 netconfAccessor.doRegisterNotificationListener(opnRdmFaultListener);
 
 144         this.opnRdmDeviceListenerRegistrationResult =
 
 145                 netconfAccessor.doRegisterNotificationListener(opnRdmDeviceListener);
 
 146         if (netconfAccessor.isNotificationsRFC5277Supported()) {
 
 147             // Register netconf stream
 
 148             netconfAccessor.registerNotificationsStream(NetconfAccessor.DefaultNotificationsStream);
 
 151             LOG.info("device {} does not support netconf notification", netconfAccessor.getNodeId().getValue());
 
 156     public void deregister() {
 
 157         if (openRdmListenerRegistrationResult != null) {
 
 158             this.openRdmListenerRegistrationResult.close();
 
 160         if (opnRdmFaultListenerRegistrationResult != null) {
 
 161             this.opnRdmFaultListenerRegistrationResult.close();
 
 163         if (opnRdmDeviceListenerRegistrationResult != null) {
 
 164             this.opnRdmDeviceListenerRegistrationResult.close();
 
 168     // end of public methods
 
 171     private void readShelvesData(List<Inventory> inventoryList, OrgOpenroadmDevice device) {
 
 172         Collection<Shelves> shelves = YangHelper.getCollection(device.getShelves());
 
 173         if (shelves != null) {
 
 174             for (Shelves shelf : shelves) {
 
 176                         "Shelf Name: {}, \n Serial Id:{}, \n Product Code;{}, \n Position:{}, \n EquipmetState: {}, \n Hardware version: {}"
 
 177                                 + "\n ShelfType:{}, \n Vendor: {}, \n LifecycleState: {} ",
 
 178                         shelf.getShelfName(), shelf.getSerialId(), shelf.getProductCode(), shelf.getShelfPosition(),
 
 179                         shelf.getEquipmentState(), shelf.getHardwareVersion(), shelf.getShelfType(), shelf.getVendor(),
 
 180                         shelf.getLifecycleState());
 
 182                         this.opnRdmInventoryInput.getShelvesInventory(shelf, Uint32.valueOf(EQUIPMENTLEVEL_BASE + 1)));
 
 183                 Collection<Slots> slotList = YangHelper.getCollection(shelf.getSlots());
 
 184                 if (slotList != null) {
 
 185                     for (Slots slot : slotList) {
 
 186                         if (slot.getProvisionedCircuitPack() != null) {
 
 187                             this.shelfProvisionedcircuitPacks.put(slot.getProvisionedCircuitPack(),
 
 188                                     EQUIPMENTLEVEL_BASE + 2);
 
 190                         LOG.info("Slots for the shelf: {}", shelf.getShelfName());
 
 191                         LOG.info("\n Slot Name: {}, \n Status: {}, \n Slot label: {} ", slot.getSlotName(),
 
 192                                 slot.getSlotStatus(), slot.getLabel());
 
 196             LOG.info("size of shelfProvisionedcircuitPacks: {} ", shelfProvisionedcircuitPacks.size());
 
 201     private void readXpndrData(List<Inventory> inventoryList, OrgOpenroadmDevice device) {
 
 202         Collection<Xponder> xponderList = YangHelper.getCollection(device.getXponder());
 
 204         if (xponderList != null) {
 
 205             for (Xponder xponder : xponderList) {
 
 207                 inventoryList.add(this.opnRdmInventoryInput.getXponderInventory(xponder,
 
 208                         Uint32.valueOf(EQUIPMENTLEVEL_BASE + 1)));
 
 209                 LOG.info("Xponders: No.: {} , \n Port: {} ,\n Type: {}", xponder.getXpdrNumber(), xponder.getXpdrPort(),
 
 210                         xponder.getXpdrType());
 
 211                 Collection<XpdrPort> xpdrportlist = YangHelper.getCollection(xponder.getXpdrPort());
 
 212                 if (xpdrportlist != null) {
 
 213                     for (XpdrPort xpdrport : xpdrportlist)
 
 214                         if (xpdrport.getCircuitPackName() != null) {
 
 215                             this.shelfProvisionedcircuitPacks.put(xpdrport.getCircuitPackName(),
 
 216                                     EQUIPMENTLEVEL_BASE + 2);
 
 217                             LOG.info("Size of dict{}", this.shelfProvisionedcircuitPacks.size());
 
 225     private void readCircuitPacketData(List<Inventory> inventoryList, OrgOpenroadmDevice device) {
 
 226         Collection<CircuitPacks> circuitpackCollection = YangHelper.getCollection(device.getCircuitPacks());
 
 227         List<String> cpNameList = new ArrayList<>();
 
 229         if (circuitpackCollection != null) {
 
 230             //            collect all circuit pack names. Required to check for invalid parents later on
 
 231             for (CircuitPacks cp : circuitpackCollection) {
 
 232                 cpNameList.add(cp.getCircuitPackName());
 
 235             for (CircuitPacks cp : circuitpackCollection) {
 
 236                 LOG.info("CP Name:{}", cp.getCircuitPackName());
 
 238                 if (cp.getParentCircuitPack() == null
 
 239                         && !this.shelfProvisionedcircuitPacks.containsKey(cp.getCircuitPackName())) {
 
 240                     LOG.info("cp has no parent and no shelf");
 
 241                     this.circuitPacksRecord.put(cp.getCircuitPackName(), (EQUIPMENTLEVEL_BASE + 1));
 
 242                     inventoryList.add(this.opnRdmInventoryInput.getCircuitPackInventory(cp,
 
 243                             Uint32.valueOf(EQUIPMENTLEVEL_BASE + 1)));
 
 245                     //                check for missing valid parent circuit name
 
 246                     if (cp.getParentCircuitPack().getCpSlotName() != null
 
 247                             && cp.getParentCircuitPack().getCircuitPackName() == null) {
 
 249                         LOG.info("Cp {} has slotname of the parent circuit pack  but no parent circuit pack name",
 
 250                                 cp.getCircuitPackName());
 
 251                         this.circuitPacksRecord.put(cp.getCircuitPackName(), (EQUIPMENTLEVEL_BASE + 3));
 
 252                         inventoryList.add(this.opnRdmInventoryInput.getCircuitPackInventory(cp,
 
 253                                 Uint32.valueOf(EQUIPMENTLEVEL_BASE + 3)));
 
 254                         databaseService.writeEventLog(writeIncorrectParentLog(cp.getCircuitPackName(), counter)
 
 255                                 .setObjectId(device.getInfo().getNodeId().getValue())
 
 256                                 .setId(cp.getParentCircuitPack().getCpSlotName())
 
 257                                 .setNewValue("Missing parent circuit pack name").build());
 
 258                     } else if (cp.getParentCircuitPack().getCircuitPackName() != null
 
 259                             && this.shelfProvisionedcircuitPacks
 
 260                                     .containsKey(cp.getParentCircuitPack().getCircuitPackName())) {
 
 261                         LOG.info("Cp {} has parent circuit pack and shelf", cp.getCircuitPackName());
 
 262                         this.circuitPacksRecord.put(cp.getCircuitPackName(), (EQUIPMENTLEVEL_BASE + 3));
 
 263                         inventoryList.add(this.opnRdmInventoryInput.getCircuitPackInventory(cp,
 
 264                                 Uint32.valueOf(EQUIPMENTLEVEL_BASE + 3)));
 
 266                         //                      check for incorrect hierarchy
 
 267                         if (cp.getParentCircuitPack().getCircuitPackName() != null
 
 268                                 && !cpNameList.contains(cp.getParentCircuitPack().getCircuitPackName())) {
 
 269                             databaseService.writeEventLog(writeIncorrectParentLog(cp.getCircuitPackName(), counter)
 
 270                                     .setObjectId(device.getInfo().getNodeId().getValue())
 
 271                                     .setId(cp.getParentCircuitPack().getCpSlotName()).build());
 
 274                         LOG.info("Cp has parent circuit pack but no shelf or a shelf but no parent circuit pack");
 
 275                         this.circuitPacksRecord.put(cp.getCircuitPackName(), (EQUIPMENTLEVEL_BASE + 2));
 
 276                         inventoryList.add(this.opnRdmInventoryInput.getCircuitPackInventory(cp,
 
 277                                 Uint32.valueOf(EQUIPMENTLEVEL_BASE + 2)));
 
 286     private void readInterfaceData(List<Inventory> inventoryList, OrgOpenroadmDevice device) {
 
 287         Collection<Interface> interfaceList = YangHelper.getCollection(device.getInterface());
 
 288         if (interfaceList != null) {
 
 289             for (Interface deviceInterface : interfaceList) {
 
 290                 LOG.info("\n InterfaceName: {}", deviceInterface.getName());
 
 291                 LOG.info("Supporting CP {}", this.circuitPacksRecord.size());
 
 292                 for (String s : this.circuitPacksRecord.keySet()) {
 
 293                     LOG.info("{} value {}", s, this.circuitPacksRecord.get(s));
 
 295                 LOG.info("Interface {} and their supporting CP {}", deviceInterface.getName(),
 
 296                         deviceInterface.getSupportingCircuitPackName());
 
 297                 if (deviceInterface.getSupportingCircuitPackName() != null) {
 
 298                     if (this.circuitPacksRecord.containsKey(deviceInterface.getSupportingCircuitPackName())) {
 
 299                         inventoryList.add(this.opnRdmInventoryInput.getInterfacesInventory(deviceInterface,
 
 301                                         this.circuitPacksRecord.get(deviceInterface.getSupportingCircuitPackName())
 
 305                     inventoryList.add(this.opnRdmInventoryInput.getInterfacesInventory(deviceInterface,
 
 306                             Uint32.valueOf(EQUIPMENTLEVEL_BASE + 1)));
 
 312     private OrgOpenroadmDevice readDevice(NetconfBindingAccessor accessor) {
 
 313         final Class<OrgOpenroadmDevice> openRoadmDev = OrgOpenroadmDevice.class;
 
 314         InstanceIdentifier<OrgOpenroadmDevice> deviceId = InstanceIdentifier.builder(openRoadmDev).build();
 
 315         return accessor.getTransactionUtils().readData(accessor.getDataBroker(), LogicalDatastoreType.OPERATIONAL,
 
 319     private EventlogBuilder writeIncorrectParentLog(String attributeName, Integer counter) {
 
 320         EventlogBuilder eventlogBuilder = new EventlogBuilder();
 
 321         eventlogBuilder.setAttributeName(attributeName).setCounter(counter)
 
 322                 .setNodeId(this.netconfAccessor.getNodeId().getValue()).setSourceType(SourceType.Netconf)
 
 323                 .setNewValue("Invalid parent circuit-pack name")
 
 324                 .setTimestamp(new DateAndTime(ncTimeConverter.getTimeStamp()));
 
 326         return eventlogBuilder;
 
 329     // end of private methods