Add protection in portmapping connection-map loop
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / mapping / PortMappingVersion221.java
index 3046aca4d61e781b690a41af095c843ffab53803..a908de054ae60bb514c866f344ae9111a6924d8e 100644 (file)
@@ -10,10 +10,8 @@ package org.opendaylight.transportpce.common.mapping;
 
 import com.google.common.util.concurrent.FluentFuture;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.math.BigInteger;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Base64;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -33,29 +31,31 @@ import org.opendaylight.transportpce.common.Timeouts;
 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.Network;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.NetworkBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.Nodes;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.NodesBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.NodesKey;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.CpToDegree;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.CpToDegreeBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.CpToDegreeKey;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.Mapping;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.MappingBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.MappingKey;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.McCapabilities;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.McCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.McCapabilitiesKey;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.NodeInfo;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.NodeInfo.OpenroadmVersion;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.NodeInfoBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.SwitchingPoolLcp;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.SwitchingPoolLcpBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.switching.pool.lcp.NonBlockingList;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.switching.pool.lcp.NonBlockingListBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.Network;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.NetworkBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.Nodes;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.NodesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.NodesKey;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.CpToDegree;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.CpToDegreeBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.CpToDegreeKey;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.Mapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.MappingBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.MappingKey;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.McCapabilities;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.McCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.McCapabilitiesKey;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.NodeInfo;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.NodeInfo.OpenroadmVersion;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.NodeInfoBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.SwitchingPoolLcp;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.SwitchingPoolLcpBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.SwitchingPoolLcpKey;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.switching.pool.lcp.NonBlockingList;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.switching.pool.lcp.NonBlockingListBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.switching.pool.lcp.NonBlockingListKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.FrequencyGHz;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.Direction;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.FrequencyGHz;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.PortQual;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.XpdrNodeTypes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.CircuitPack;
@@ -76,9 +76,11 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.open
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.Xponder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.connection.map.Destination;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.odu.switching.pools.non.blocking.list.PortList;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.port.Interfaces;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.xponder.XpdrPort;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.InterfaceType;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.OpenROADMOpticalMultiplex;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.OpticalTransport;
@@ -86,22 +88,22 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.OtnO
 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.Protocols1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.lldp.container.Lldp;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.lldp.container.lldp.PortConfig;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181019.SupportedIfCapability;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.switching.pool.types.rev191129.SwitchingPoolTypes;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+// FIXME: many common pieces of code between PortMapping Versions 121 and 221 and 710
+// some mutualization would be helpful
 public class PortMappingVersion221 {
     private static final Logger LOG = LoggerFactory.getLogger(PortMappingVersion221.class);
 
     private final DataBroker dataBroker;
     private final DeviceTransactionManager deviceTransactionManager;
     private final OpenRoadmInterfaces openRoadmInterfaces;
-    //FNV1 64 bit hash constants
-    private static final BigInteger FNV_PRIME = new BigInteger("100000001b3", 16);
-    private static final BigInteger FNV_INIT = new BigInteger("cbf29ce484222325", 16);
-    private static final BigInteger FNV_MOD = new BigInteger("2").pow(64);
 
     public PortMappingVersion221(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
         OpenRoadmInterfaces openRoadmInterfaces) {
@@ -118,14 +120,12 @@ public class PortMappingVersion221 {
         Optional<Info> deviceInfoOptional = this.deviceTransactionManager.getDataFromDevice(
                 nodeId, LogicalDatastoreType.OPERATIONAL, infoIID,
                 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
-        Info deviceInfo;
-        NodeInfo nodeInfo;
         if (!deviceInfoOptional.isPresent()) {
             LOG.warn("Device info subtree is absent for {}", nodeId);
             return false;
         }
-        deviceInfo = deviceInfoOptional.get();
-        nodeInfo = createNodeInfo(deviceInfo, nodeId);
+        Info deviceInfo = deviceInfoOptional.get();
+        NodeInfo nodeInfo = createNodeInfo(deviceInfo);
         if (nodeInfo == null) {
             return false;
         }
@@ -208,25 +208,22 @@ public class PortMappingVersion221 {
         Optional<OrgOpenroadmDevice> deviceObject = deviceTransactionManager.getDataFromDevice(nodeId,
             LogicalDatastoreType.OPERATIONAL, deviceIID,
             Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
-        OrgOpenroadmDevice device = null;
         if (!deviceObject.isPresent()) {
             LOG.error("Impossible to get device configuration for node {}", nodeId);
             return false;
         }
-        device = deviceObject.get();
+        OrgOpenroadmDevice device = deviceObject.get();
+        if (device.getCircuitPacks() == null) {
+            LOG.warn("Circuit Packs are not present for {}", nodeId);
+            return false;
+        }
         // Variable to keep track of number of line ports
         int line = 1;
         // Variable to keep track of number of client ports
         int client = 1;
         Map<String, String> lcpMap = new HashMap<>();
         Map<String, Mapping> mappingMap = new HashMap<>();
-
-        List<CircuitPacks> circuitPackList = null;
-        if (device.getCircuitPacks() == null) {
-            LOG.warn("Circuit Packs are not present for {}", nodeId);
-            return false;
-        }
-        circuitPackList = new ArrayList<>(deviceObject.get().getCircuitPacks());
+        List<CircuitPacks> circuitPackList = new ArrayList<>(device.nonnullCircuitPacks().values());
         circuitPackList.sort(Comparator.comparing(CircuitPack::getCircuitPackName));
 
         if (device.getXponder() == null) {
@@ -237,7 +234,7 @@ public class PortMappingVersion221 {
                     LOG.warn("Ports were not found for circuit pack: {}", circuitPackName);
                     continue;
                 }
-                List<Ports> portList = new ArrayList<>(cp.getPorts());
+                List<Ports> portList = new ArrayList<>(cp.nonnullPorts().values());
                 portList.sort(Comparator.comparing(Ports::getPortName));
                 for (Ports port : portList) {
                     if (port.getPortQual() == null) {
@@ -265,7 +262,7 @@ public class PortMappingVersion221 {
                             .filter(cP -> cP.getCircuitPackName().equals(port.getPartnerPort().getCircuitPackName()))
                             .findFirst();
                         if (cpOpt.isPresent()) {
-                            Optional<Ports> poOpt = cpOpt.get().getPorts().stream()
+                            Optional<Ports> poOpt = cpOpt.get().nonnullPorts().values().stream()
                                 .filter(p -> p.getPortName().equals(port.getPartnerPort().getPortName().toString()))
                                 .findFirst();
                             if (poOpt.isPresent()) {
@@ -312,35 +309,35 @@ public class PortMappingVersion221 {
             }
         } else {
             LOG.info("{} configuration contains a list of xponders", nodeId);
-            for (Xponder xponder:deviceObject.get().getXponder()) {
+            for (Xponder xponder:deviceObject.get().nonnullXponder().values()) {
                 line = 1;
                 client = 1;
                 Integer xponderNb = xponder.getXpdrNumber().toJava();
                 XpdrNodeTypes xponderType = xponder.getXpdrType();
-                for (XpdrPort xpdrPort : xponder.getXpdrPort()) {
+                for (XpdrPort xpdrPort : xponder.nonnullXpdrPort().values()) {
                     String circuitPackName = xpdrPort.getCircuitPackName();
                     String portName = xpdrPort.getPortName().toString();
                     // If there xponder-subtree has missing circuit-packs or ports,
                     // This gives a null-pointer expection,
-                    if (device.getCircuitPacks().stream()
+                    if (device.nonnullCircuitPacks().values().stream()
                             .filter(cp -> cp.getCircuitPackName().equals(circuitPackName))
                             .findFirst().isEmpty()) {
                         LOG.warn("Circuit-pack {} is missing in the device", circuitPackName);
                         LOG.warn("Port-mapping will continue ignoring this circuit-pack {}", circuitPackName);
                         continue;
                     }
-                    if (device.getCircuitPacks().stream()
+                    if (device.nonnullCircuitPacks().values().stream()
                             .filter(cp -> cp.getCircuitPackName().equals(circuitPackName))
-                            .findFirst().get().getPorts().stream()
+                            .findFirst().get().nonnullPorts().values().stream()
                             .filter(p -> p.getPortName().equals(portName))
                             .findFirst().isEmpty()) {
                         LOG.warn("Port {} associated with CP {} is missing in the device", portName, circuitPackName);
                         LOG.warn("Port-mapping will continue ignoring this port {}", portName);
                         continue;
                     }
-                    Ports port = device.getCircuitPacks().stream()
+                    Ports port = device.nonnullCircuitPacks().values().stream()
                             .filter(cp -> cp.getCircuitPackName().equals(circuitPackName))
-                            .findFirst().get().getPorts().stream()
+                            .findFirst().get().nonnullPorts().values().stream()
                             .filter(p -> p.getPortName().equals(portName))
                             .findFirst().get();
                     if (port.getPortQual() == null) {
@@ -371,7 +368,7 @@ public class PortMappingVersion221 {
                             .filter(cP -> cP.getCircuitPackName().equals(port.getPartnerPort().getCircuitPackName()))
                             .findFirst();
                         if (cpOpt.isPresent()) {
-                            Optional<Ports> poOpt = cpOpt.get().getPorts().stream()
+                            Optional<Ports> poOpt = cpOpt.get().nonnullPorts().values().stream()
                                 .filter(p -> p.getPortName().equals(port.getPartnerPort().getPortName().toString()))
                                 .findFirst();
                             if (poOpt.isPresent()) {
@@ -421,41 +418,43 @@ public class PortMappingVersion221 {
             }
         }
 
-        if (device.getConnectionMap() != null) {
-            List<ConnectionMap> connectionMap = deviceObject.get().getConnectionMap();
-            String slcp = null;
-            String dlcp = null;
+        if (device.getConnectionMap() == null) {
+            LOG.warn("No connection-map inside device configuration");
+        } else {
+            Collection<ConnectionMap> connectionMap = deviceObject.get().nonnullConnectionMap().values();
             for (ConnectionMap cm : connectionMap) {
+                String slcp = null;
+                String dlcp = null;
                 String skey = cm.getSource().getCircuitPackName() + "+" + cm.getSource().getPortName();
                 if (lcpMap.containsKey(skey)) {
                     slcp = lcpMap.get(skey);
                 }
-                String dkey = cm.getDestination().get(0).getCircuitPackName() + "+"
-                    + cm.getDestination().get(0).getPortName();
+                Destination destination0 = cm.nonnullDestination().values().iterator().next();
+                String dkey = destination0.getCircuitPackName() + "+" + destination0.getPortName();
+                if (slcp == null) {
+                    LOG.error("Error in connection-map analysis for source {} and destination (circuitpack+port) {}",
+                        skey, dkey);
+                    continue;
+                }
                 if (lcpMap.containsKey(dkey)) {
                     dlcp = lcpMap.get(dkey);
                 }
-                if (slcp != null) {
-                    Mapping mapping = mappingMap.get(slcp);
-                    mappingMap.remove(slcp);
-                    portMapList.add(createXpdrMappingObject(nodeId, null, null, null, null, mapping, dlcp, null));
-                } else {
-                    LOG.error("Error in connection-map analysis");
-                }
+                Mapping mapping = mappingMap.get(slcp);
+                mappingMap.remove(slcp);
+                portMapList.add(createXpdrMappingObject(nodeId, null, null, null, null, mapping, dlcp, null));
             }
-        } else {
-            LOG.warn("No connection-map inside device configuration");
         }
+
         if (device.getOduSwitchingPools() != null) {
-            List<OduSwitchingPools> oduSwithcingPools = device.getOduSwitchingPools();
+            Collection<OduSwitchingPools> oduSwithcingPools = device.nonnullOduSwitchingPools().values();
             List<SwitchingPoolLcp> switchingPoolList = new ArrayList<>();
             for (OduSwitchingPools odp : oduSwithcingPools) {
-                List<NonBlockingList> nblList = new ArrayList<>();
+                Map<NonBlockingListKey,NonBlockingList> nbMap = new HashMap<>();
                 for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org
-                    .openroadm.device.odu.switching.pools.NonBlockingList nbl : odp.getNonBlockingList()) {
+                    .openroadm.device.odu.switching.pools.NonBlockingList nbl : odp.nonnullNonBlockingList().values()) {
                     List<String> lcpList = new ArrayList<>();
                     if (nbl.getPortList() != null) {
-                        for (PortList item : nbl.getPortList()) {
+                        for (PortList item : nbl.nonnullPortList().values()) {
                             String key = item.getCircuitPackName() + "+" + item.getPortName();
                             if (lcpMap.containsKey(key)) {
                                 lcpList.add(lcpMap.get(key));
@@ -470,13 +469,13 @@ public class PortMappingVersion221 {
                             .setInterconnectBandwidthUnit(nbl.getInterconnectBandwidthUnit())
                             .setLcpList(lcpList)
                             .build();
-                        nblList.add(nonBlockingList);
+                        nbMap.put(nonBlockingList.key(), nonBlockingList);
                     }
                 }
                 SwitchingPoolLcp splBldr = new SwitchingPoolLcpBuilder()
                     .setSwitchingPoolNumber(odp.getSwitchingPoolNumber())
-                    .setSwitchingPoolType(odp.getSwitchingPoolType())
-                    .setNonBlockingList(nblList)
+                    .setSwitchingPoolType(SwitchingPoolTypes.forValue(odp.getSwitchingPoolType().getIntValue()))
+                    .setNonBlockingList(nbMap)
                     .build();
                 switchingPoolList.add(splBldr);
             }
@@ -534,7 +533,7 @@ public class PortMappingVersion221 {
                 LogicalDatastoreType.OPERATIONAL, srgIID,
                 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
             if (ordmSrgObject.isPresent()) {
-                srgCps.addAll(ordmSrgObject.get().getCircuitPacks());
+                srgCps.addAll(ordmSrgObject.get().nonnullCircuitPacks().values());
                 cpPerSrg.put(ordmSrgObject.get().getSrgNumber().toJava(), srgCps);
             }
         }
@@ -564,7 +563,7 @@ public class PortMappingVersion221 {
                     LOG.warn("{} : Circuit pack {} not found or without ports.", nodeId, circuitPackName);
                     continue;
                 }
-                List<Ports> portList = new ArrayList<>(circuitPackObject.get().getPorts());
+                List<Ports> portList = new ArrayList<>(circuitPackObject.get().nonnullPorts().values());
                 Collections.sort(portList, new SortPort221ByName());
                 int portIndex = 1;
                 for (Ports port : portList) {
@@ -718,7 +717,8 @@ public class PortMappingVersion221 {
                 LogicalDatastoreType.OPERATIONAL, deviceIID,
                 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
             if (ordmDegreeObject.isPresent()) {
-                conPortMap.put(degreeCounter, ordmDegreeObject.get().getConnectionPorts());
+                conPortMap.put(degreeCounter, new ArrayList<>(ordmDegreeObject.get()
+                        .nonnullConnectionPorts().values()));
             }
         }
         LOG.info("Device {} has {} degree", deviceId, conPortMap.size());
@@ -735,7 +735,7 @@ public class PortMappingVersion221 {
             Timeouts.DEVICE_READ_TIMEOUT_UNIT);
         if (protocolObject.isPresent() && protocolObject.get().augmentation(Protocols1.class).getLldp() != null) {
             Lldp lldp = protocolObject.get().augmentation(Protocols1.class).getLldp();
-            for (PortConfig portConfig : lldp.getPortConfig()) {
+            for (PortConfig portConfig : lldp.nonnullPortConfig().values()) {
                 if (portConfig.getAdminStatus().equals(PortConfig.AdminStatus.Txandrx)) {
                     InstanceIdentifier<Interface> interfaceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
                         .child(Interface.class, new InterfaceKey(portConfig.getIfName()));
@@ -771,7 +771,7 @@ public class PortMappingVersion221 {
         for (Degree degree : degrees) {
             if (degree.getCircuitPacks() != null) {
                 LOG.info("Inside CP to degree list");
-                cpToDegreeList.addAll(degree.getCircuitPacks().stream()
+                cpToDegreeList.addAll(degree.nonnullCircuitPacks().values().stream()
                     .map(cp -> createCpToDegreeObject(cp.getCircuitPackName(),
                         degree.getDegreeNumber().toString(), nodeId, interfaceList))
                     .collect(Collectors.toList()));
@@ -799,25 +799,44 @@ public class PortMappingVersion221 {
             nodesBldr.setNodeInfo(nodeInfo);
         }
         if (portMapList != null) {
-            nodesBldr.setMapping(portMapList);
+            Map<MappingKey, Mapping> mappingMap = new HashMap<>();
+            for (Mapping mapping: portMapList) {
+                if (mapping != null) {
+                    mappingMap.put(mapping.key(), mapping);
+                }
+            }
+            nodesBldr.setMapping(mappingMap);
         }
         if (cp2DegreeList != null) {
-            nodesBldr.setCpToDegree(cp2DegreeList);
+            Map<CpToDegreeKey, CpToDegree> cpToDegreeMap = new HashMap<>();
+            for (CpToDegree cp2Degree: cp2DegreeList) {
+                if (cp2Degree != null) {
+                    cpToDegreeMap.put(cp2Degree.key(), cp2Degree);
+                }
+            }
+            nodesBldr.setCpToDegree(cpToDegreeMap);
         }
+
         if (splList != null) {
-            nodesBldr.setSwitchingPoolLcp(splList);
+            Map<SwitchingPoolLcpKey,SwitchingPoolLcp> splMap = new HashMap<>();
+            for (SwitchingPoolLcp spl: splList) {
+                if (spl != null) {
+                    splMap.put(spl.key(), spl);
+                }
+            }
+            nodesBldr.setSwitchingPoolLcp(splMap);
         }
         if (mcCapList != null) {
             nodesBldr.setMcCapabilities(mcCapList);
         }
-        List<Nodes> nodesList = new ArrayList<>();
-        nodesList.add(nodesBldr.build());
+        Map<NodesKey,Nodes> nodesList = new HashMap<>();
+        Nodes nodes = nodesBldr.build();
+        nodesList.put(nodes.key(),nodes);
 
-        NetworkBuilder nwBldr = new NetworkBuilder().setNodes(nodesList);
+        Network network = new NetworkBuilder().setNodes(nodesList).build();
 
         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
         InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
-        Network network = nwBldr.build();
         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, network);
         FluentFuture<? extends @NonNull CommitInfo> commit = writeTransaction.commit();
         try {
@@ -846,8 +865,10 @@ public class PortMappingVersion221 {
             .setMcNodeName(mcNodeName);
         if (degree.getMcCapabilities() != null) {
             mcCapabilitiesBuilder
-                .setCenterFreqGranularity(degree.getMcCapabilities().getCenterFreqGranularity())
-                .setSlotWidthGranularity(degree.getMcCapabilities().getSlotWidthGranularity());
+                .setCenterFreqGranularity(FrequencyGHz.getDefaultInstance(degree.getMcCapabilities()
+                    .getCenterFreqGranularity().getValue().toString()))
+                .setSlotWidthGranularity(FrequencyGHz.getDefaultInstance(degree.getMcCapabilities()
+                    .getSlotWidthGranularity().getValue().toString()));
         }
         else {
             LOG.warn("Media channel capabilities are not advertised for degree {} of {}", degree.getDegreeNumber(),
@@ -868,8 +889,10 @@ public class PortMappingVersion221 {
             .setMcNodeName(mcNodeName);
         if (srg.getMcCapabilities() != null) {
             mcCapabilitiesBuilder
-                .setCenterFreqGranularity(srg.getMcCapabilities().getCenterFreqGranularity())
-                .setSlotWidthGranularity(srg.getMcCapabilities().getSlotWidthGranularity());
+                .setCenterFreqGranularity(FrequencyGHz.getDefaultInstance(srg.getMcCapabilities()
+                    .getCenterFreqGranularity().getValue().toString()))
+                .setSlotWidthGranularity(FrequencyGHz.getDefaultInstance(srg.getMcCapabilities()
+                    .getSlotWidthGranularity().getValue().toString()));
         }
         else {
             LOG.warn("Media channel capabilities are not advertised for SRG {} of {}", srg.getSrgNumber(),
@@ -884,11 +907,14 @@ public class PortMappingVersion221 {
     }
 
     private Mapping createMappingObject(String nodeId, Ports port, String circuitPackName,
-        String logicalConnectionPoint) {
-        MappingBuilder mpBldr = new MappingBuilder();
-        mpBldr.withKey(new MappingKey(logicalConnectionPoint)).setLogicalConnectionPoint(logicalConnectionPoint)
-            .setSupportingCircuitPackName(circuitPackName).setSupportingPort(port.getPortName())
-            .setPortDirection(port.getPortDirection().getName());
+            String logicalConnectionPoint) {
+
+        MappingBuilder mpBldr = new MappingBuilder()
+                .withKey(new MappingKey(logicalConnectionPoint))
+                .setLogicalConnectionPoint(logicalConnectionPoint)
+                .setSupportingCircuitPackName(circuitPackName)
+                .setSupportingPort(port.getPortName())
+                .setPortDirection(port.getPortDirection().getName());
 
         // Get OMS and OTS interface provisioned on the TTP's
         if ((logicalConnectionPoint.contains(StringConstants.TTP_TOKEN)
@@ -927,43 +953,50 @@ public class PortMappingVersion221 {
     private Mapping createXpdrMappingObject(String nodeId, Ports port, String circuitPackName,
             String logicalConnectionPoint, String partnerLcp, Mapping mapping, String connectionMapLcp,
             XpdrNodeTypes xpdrNodeType) {
-        MappingBuilder mpBldr;
+
         if (mapping != null && connectionMapLcp != null) {
             // update existing mapping
-            mpBldr = new MappingBuilder(mapping).setConnectionMapLcp(connectionMapLcp);
-        } else {
-            // create a new mapping
-            String nodeIdLcp = nodeId + "-" + logicalConnectionPoint;
-            mpBldr = new MappingBuilder()
+            return new MappingBuilder(mapping).setConnectionMapLcp(connectionMapLcp).build();
+        }
+
+        // create a new mapping
+        String nodeIdLcp = nodeId + "-" + logicalConnectionPoint;
+        MappingBuilder mpBldr = new MappingBuilder()
                 .withKey(new MappingKey(logicalConnectionPoint))
                 .setLogicalConnectionPoint(logicalConnectionPoint)
                 .setSupportingCircuitPackName(circuitPackName)
                 .setSupportingPort(port.getPortName())
                 .setPortDirection(port.getPortDirection().getName())
-                .setLcpHashVal(fnv(nodeIdLcp));
-
-            if (port.getPortQual() != null) {
-                mpBldr.setPortQual(port.getPortQual().getName());
-            }
-            if (port.getSupportedInterfaceCapability() != null) {
-                mpBldr.setSupportedInterfaceCapability(port.getSupportedInterfaceCapability());
-            }
-            if (xpdrNodeType != null) {
-                mpBldr.setXponderType(xpdrNodeType);
-            }
-            if (partnerLcp != null) {
-                mpBldr.setPartnerLcp(partnerLcp);
+                .setLcpHashVal(FnvUtils.fnv1_64(nodeIdLcp));
+        if (port.getPortQual() != null) {
+            mpBldr.setPortQual(port.getPortQual().getName());
+        }
+        if (xpdrNodeType != null) {
+            mpBldr.setXponderType(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129
+                    .XpdrNodeTypes.forValue(xpdrNodeType.getIntValue()));
+        }
+        if (partnerLcp != null) {
+            mpBldr.setPartnerLcp(partnerLcp);
+        }
+        if (port.getSupportedInterfaceCapability() != null) {
+            List<Class<? extends org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327
+                .SupportedIfCapability>> supportedIntf = new ArrayList<>();
+            for (Class<? extends SupportedIfCapability> sup: port.getSupportedInterfaceCapability()) {
+                Class<? extends org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327
+                    .SupportedIfCapability> sup1 = (Class<? extends org.opendaylight.yang.gen.v1
+                        .http.org.openroadm.port.types.rev200327.SupportedIfCapability>) sup;
+                supportedIntf.add(sup1);
             }
+            mpBldr.setSupportedInterfaceCapability(supportedIntf);
         }
         return mpBldr.build();
     }
 
-
     private boolean createMcCapabilitiesList(String nodeId, Info deviceInfo, List<McCapabilities> mcCapabilitiesList) {
         List<Degree> degrees = getDegrees(nodeId, deviceInfo);
         List<SharedRiskGroup> srgs = getSrgs(nodeId, deviceInfo);
         mcCapabilitiesList.addAll(getMcCapabilitiesList(degrees, srgs, nodeId));
-
         return true;
     }
 
@@ -1100,29 +1133,28 @@ public class PortMappingVersion221 {
         return true;
     }
 
-    private NodeInfo createNodeInfo(Info deviceInfo, String nodeId) {
-        NodeInfoBuilder nodeInfoBldr = new NodeInfoBuilder();
+    private NodeInfo createNodeInfo(Info deviceInfo) {
+
         if (deviceInfo.getNodeType() == null) {
             // TODO make mandatory in yang
             LOG.error("Node type field is missing");
             return null;
         }
 
-        nodeInfoBldr.setOpenroadmVersion(OpenroadmVersion._221).setNodeType(deviceInfo.getNodeType());
+        NodeInfoBuilder nodeInfoBldr = new NodeInfoBuilder()
+                .setOpenroadmVersion(OpenroadmVersion._221)
+                .setNodeType(NodeTypes.forValue(deviceInfo.getNodeType().getIntValue()));
         if (deviceInfo.getClli() != null && !deviceInfo.getClli().isEmpty()) {
             nodeInfoBldr.setNodeClli(deviceInfo.getClli());
         } else {
             nodeInfoBldr.setNodeClli("defaultCLLI");
         }
-
         if (deviceInfo.getModel() != null) {
             nodeInfoBldr.setNodeModel(deviceInfo.getModel());
         }
-
         if (deviceInfo.getVendor() != null) {
             nodeInfoBldr.setNodeVendor(deviceInfo.getVendor());
         }
-
         if (deviceInfo.getIpAddress() != null) {
             nodeInfoBldr.setNodeIpAddress(deviceInfo.getIpAddress());
         }
@@ -1130,24 +1162,4 @@ public class PortMappingVersion221 {
         return nodeInfoBldr.build();
     }
 
-    /**
-     * Implements the FNV-1 64bit algorithm.
-     * FNV-1 128bit would be ideal for 16 bytes but we need an overhead for Base64 encoding.
-     * Otherwise, the hash cannot be stored in a UTF-8 string.
-     * https://www.wikiwand.com/en/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#/FNV-1_hash
-     * https://github.com/pmdamora/fnv-cracker-app/blob/master/src/main/java/passwordcrack/cracking/HashChecker.java
-     * @param stringdata the String to be hashed
-     * @return the hash string
-     */
-    private String fnv(String stringdata) {
-        BigInteger hash = FNV_INIT;
-        byte[] data = stringdata.getBytes(StandardCharsets.UTF_8);
-
-        for (byte b : data) {
-            hash = hash.multiply(FNV_PRIME).mod(FNV_MOD);
-            hash = hash.xor(BigInteger.valueOf((int) b & 0xff));
-        }
-
-        return Base64.getEncoder().encodeToString(hash.toByteArray());
-    }
 }