Add protection in portmapping connection-map loop
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / mapping / PortMappingVersion710.java
index bac76e0dd1cc022ab70c936464f41877b0bdd242..9eb0cf9f6048c41db228e857129f8638794782d1 100644 (file)
@@ -10,10 +10,7 @@ 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;
@@ -92,26 +89,20 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.OtnO
 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev200529.Protocols1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev200529.lldp.container.Lldp;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev200529.lldp.container.lldp.PortConfig;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.port.capability.rev200529.Ports1;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.port.capability.rev200529.port.capability.grp.port.capabilities.SupportedInterfaceCapability;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.port.capability.rev200529.port.capability.grp.port.capabilities.SupportedInterfaceCapabilityKey;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.SupportedIfCapability;
 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 PortMappingVersion710 {
     private static final Logger LOG = LoggerFactory.getLogger(PortMappingVersion710.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 PortMappingVersion710(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
         OpenRoadmInterfaces openRoadmInterfaces) {
@@ -128,14 +119,12 @@ public class PortMappingVersion710 {
         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;
         }
@@ -218,25 +207,22 @@ public class PortMappingVersion710 {
         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().nonnullCircuitPacks().values());
+        List<CircuitPacks> circuitPackList = new ArrayList<>(device.nonnullCircuitPacks().values());
         circuitPackList.sort(Comparator.comparing(CircuitPack::getCircuitPackName));
 
         if (device.getXponder() == null) {
@@ -431,31 +417,33 @@ public class PortMappingVersion710 {
             }
         }
 
-        if (device.getConnectionMap() != null) {
+        if (device.getConnectionMap() == null) {
+            LOG.warn("No connection-map inside device configuration");
+        } else {
             Collection<ConnectionMap> connectionMap = deviceObject.get().nonnullConnectionMap().values();
-            String slcp = null;
-            String dlcp = null;
             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);
                 }
                 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) {
             Collection<OduSwitchingPools> oduSwithcingPools = device.nonnullOduSwitchingPools().values();
             List<SwitchingPoolLcp> switchingPoolList = new ArrayList<>();
@@ -864,11 +852,10 @@ public class PortMappingVersion710 {
         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 {
@@ -891,24 +878,12 @@ public class PortMappingVersion710 {
     }
 
     private List<McCapabilities> createMcCapDegreeObject(List<Degree> degrees,
-        Map<McCapabilityProfileKey, McCapabilityProfile> mcCapabilityProfileMap, String nodeId) {
+            Map<McCapabilityProfileKey, McCapabilityProfile> mcCapabilityProfileMap, String nodeId) {
+
         List<McCapabilities> mcCapabilitiesList = new ArrayList<>();
         for (Degree degree : degrees) {
-            if (!degree.getMcCapabilityProfileName().isEmpty()) {
-                for (String mcCapabilityProfileName : degree.getMcCapabilityProfileName()) {
-                    McCapabilityProfileKey mcKey = new McCapabilityProfileKey(mcCapabilityProfileName);
-                    McCapabilityProfile mcCapabilityProfile = mcCapabilityProfileMap.get(mcKey);
-                    String mcNodeName = "DEG" + degree.getDegreeNumber().toString() + "-TTP-" + mcCapabilityProfile;
-                    McCapabilitiesBuilder mcCapabilitiesBuilder = new McCapabilitiesBuilder()
-                        .withKey(new McCapabilitiesKey(mcNodeName))
-                        .setMcNodeName(mcNodeName);
-                    mcCapabilitiesBuilder
-                        .setCenterFreqGranularity(mcCapabilityProfile.getCenterFreqGranularity())
-                        .setSlotWidthGranularity(mcCapabilityProfile.getSlotWidthGranularity());
-                    mcCapabilitiesList.add(mcCapabilitiesBuilder.build());
-                } // end for
-            }
-            else {
+
+            if ((degree.getMcCapabilityProfileName() == null) || (degree.getMcCapabilityProfileName().isEmpty())) {
                 LOG.warn("No MC profiles are found for  node {} on degree {}", nodeId, degree.getDegreeNumber());
                 LOG.warn("Assuming the fixed grid capabilities for degree {}", degree.getDegreeNumber());
                 LOG.warn("Assuming a default MC profile-name for degree {}", degree.getDegreeNumber());
@@ -919,30 +894,34 @@ public class PortMappingVersion710 {
                 mcCapabilitiesBuilder
                     .setCenterFreqGranularity(FrequencyGHz.getDefaultInstance("50"))
                     .setSlotWidthGranularity(FrequencyGHz.getDefaultInstance("50"));
+                mcCapabilitiesList.add(mcCapabilitiesBuilder.build());
+                continue;
             }
+
+            for (String mcCapabilityProfileName : degree.getMcCapabilityProfileName()) {
+                McCapabilityProfileKey mcKey = new McCapabilityProfileKey(mcCapabilityProfileName);
+                McCapabilityProfile mcCapabilityProfile = mcCapabilityProfileMap.get(mcKey);
+                String mcNodeName = "DEG" + degree.getDegreeNumber().toString() + "-TTP-" + mcCapabilityProfile;
+                McCapabilitiesBuilder mcCapabilitiesBuilder = new McCapabilitiesBuilder()
+                    .withKey(new McCapabilitiesKey(mcNodeName))
+                    .setMcNodeName(mcNodeName);
+                mcCapabilitiesBuilder
+                    .setCenterFreqGranularity(mcCapabilityProfile.getCenterFreqGranularity())
+                    .setSlotWidthGranularity(mcCapabilityProfile.getSlotWidthGranularity());
+                mcCapabilitiesList.add(mcCapabilitiesBuilder.build());
+            }
+
         }
         return mcCapabilitiesList;
     }
 
     private List<McCapabilities> createMcCapSrgObject(List<SharedRiskGroup> srgs,
-        Map<McCapabilityProfileKey, McCapabilityProfile> mcCapabilityProfileMap, String nodeId) {
+            Map<McCapabilityProfileKey, McCapabilityProfile> mcCapabilityProfileMap, String nodeId) {
+
         List<McCapabilities> mcCapabilitiesList = new ArrayList<>();
         for (SharedRiskGroup srg : srgs) {
-            if (!srg.getMcCapabilityProfileName().isEmpty()) {
-                for (String mcCapabilityProfileName : srg.getMcCapabilityProfileName()) {
-                    McCapabilityProfileKey mcKey = new McCapabilityProfileKey(mcCapabilityProfileName);
-                    McCapabilityProfile mcCapabilityProfile = mcCapabilityProfileMap.get(mcKey);
-                    String mcNodeName = "SRG" + srg.getSrgNumber().toString() + "-PP-" + mcCapabilityProfile;
-                    McCapabilitiesBuilder mcCapabilitiesBuilder = new McCapabilitiesBuilder()
-                        .withKey(new McCapabilitiesKey(mcNodeName))
-                        .setMcNodeName(mcNodeName);
-                    mcCapabilitiesBuilder
-                        .setCenterFreqGranularity(mcCapabilityProfile.getCenterFreqGranularity())
-                        .setSlotWidthGranularity(mcCapabilityProfile.getSlotWidthGranularity());
-                    mcCapabilitiesList.add(mcCapabilitiesBuilder.build());
-                } // end for
-            }
-            else {
+
+            if ((srg.getMcCapabilityProfileName() == null) || (srg.getMcCapabilityProfileName().isEmpty())) {
                 LOG.warn("No MC profiles are found for  node {} on SRG {}", nodeId, srg.getSrgNumber());
                 LOG.warn("Assuming the fixed grid capabilities for SRG {}", srg.getSrgNumber());
                 LOG.warn("Assuming a default MC profile-name for SRG {}", srg.getSrgNumber());
@@ -953,17 +932,35 @@ public class PortMappingVersion710 {
                 mcCapabilitiesBuilder
                     .setCenterFreqGranularity(FrequencyGHz.getDefaultInstance("50"))
                     .setSlotWidthGranularity(FrequencyGHz.getDefaultInstance("50"));
+                mcCapabilitiesList.add(mcCapabilitiesBuilder.build());
+                continue;
+            }
+
+            for (String mcCapabilityProfileName : srg.getMcCapabilityProfileName()) {
+                McCapabilityProfileKey mcKey = new McCapabilityProfileKey(mcCapabilityProfileName);
+                McCapabilityProfile mcCapabilityProfile = mcCapabilityProfileMap.get(mcKey);
+                String mcNodeName = "SRG" + srg.getSrgNumber().toString() + "-PP-" + mcCapabilityProfile;
+                McCapabilitiesBuilder mcCapabilitiesBuilder = new McCapabilitiesBuilder()
+                    .withKey(new McCapabilitiesKey(mcNodeName))
+                    .setMcNodeName(mcNodeName);
+                mcCapabilitiesBuilder
+                    .setCenterFreqGranularity(mcCapabilityProfile.getCenterFreqGranularity())
+                    .setSlotWidthGranularity(mcCapabilityProfile.getSlotWidthGranularity());
+                mcCapabilitiesList.add(mcCapabilitiesBuilder.build());
             }
         }
         return mcCapabilitiesList;
     }
 
     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)
@@ -1000,51 +997,35 @@ public class PortMappingVersion710 {
     }
 
     private Mapping createXpdrMappingObject(String nodeId, Ports ports, String circuitPackName,
-        String logicalConnectionPoint, String partnerLcp, Mapping mapping, String connectionMapLcp,
-        XpdrNodeTypes xpdrNodeType) {
-        MappingBuilder mpBldr;
+            String logicalConnectionPoint, String partnerLcp, Mapping mapping, String connectionMapLcp,
+            XpdrNodeTypes xpdrNodeType) {
+
         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(ports.getPortName())
                 .setPortDirection(ports.getPortDirection().getName())
-                .setLcpHashVal(fnv(nodeIdLcp));
-
-            if (ports.getPortQual() != null) {
-                mpBldr.setPortQual(ports.getPortQual().getName());
-            }
-
-            if (ports.augmentation(Ports1.class).getPortCapabilities().getSupportedInterfaceCapability() != null) {
-                mpBldr.setSupportedInterfaceCapability(getSupportedIfCapability(ports));
-            }
-
-            if (xpdrNodeType != null) {
-                mpBldr.setXponderType(xpdrNodeType);
-            }
-            if (partnerLcp != null) {
-                mpBldr.setPartnerLcp(partnerLcp);
-            }
+                .setLcpHashVal(FnvUtils.fnv1_64(nodeIdLcp));
+        if (ports.getPortQual() != null) {
+            mpBldr.setPortQual(ports.getPortQual().getName());
+        }
+        if (xpdrNodeType != null) {
+            mpBldr.setXponderType(xpdrNodeType);
+        }
+        if (partnerLcp != null) {
+            mpBldr.setPartnerLcp(partnerLcp);
         }
         return mpBldr.build();
     }
 
-
-    private List<Class<? extends SupportedIfCapability>> getSupportedIfCapability(Ports ports) {
-        Map<SupportedInterfaceCapabilityKey, SupportedInterfaceCapability> supportedInterfaceCapabilityMap =
-            ports.augmentation(Ports1.class).getPortCapabilities().getSupportedInterfaceCapability();
-        List<Class<? extends SupportedIfCapability>> supportedInterfaceCapabilityList = new ArrayList<>();
-
-        supportedInterfaceCapabilityMap.forEach((k, v) -> supportedInterfaceCapabilityList.add(k.getIfCapType()));
-        return supportedInterfaceCapabilityList;
-    }
-
     private boolean createMcCapabilitiesList(String nodeId, Info deviceInfo, List<McCapabilities> mcCapabilitiesList) {
         List<Degree> degrees = getDegrees(nodeId, deviceInfo);
         List<SharedRiskGroup> srgs = getSrgs(nodeId, deviceInfo);
@@ -1186,54 +1167,33 @@ public class PortMappingVersion710 {
         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._710).setNodeType(deviceInfo.getNodeType());
+        NodeInfoBuilder nodeInfoBldr = new NodeInfoBuilder()
+                .setOpenroadmVersion(OpenroadmVersion._710)
+                .setNodeType(deviceInfo.getNodeType());
+        // TODO: 221 versions expects an int value - need to check whether it is bug or an evolution here
         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());
         }
 
         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());
-    }
 }