Update portmapping with switching-pool from notif 77/96077/3
authorGilles Thouenon <gilles.thouenon@orange.com>
Fri, 7 May 2021 08:41:18 +0000 (10:41 +0200)
committerBalagangadhar Bathula <bb4341@att.com>
Tue, 3 Aug 2021 13:18:10 +0000 (09:18 -0400)
Update the switching-pool-lcp list of portmapping from a
change-notification received from a 7.1 muxponder device. Manage such a
7.1 device notification to create, or update if object already exists,
the switching-pool-lcp container abstracting the device
odu-switching-pools one.
- add new updatePortMappingWithOduSwitchingPools method in PortMapping
interface
- implement this method in PortMappingImpl and PortMappingVersion710
classes
- keep the existing building of switching-pool-lcp in
createXpdrPortMapping method in case existing odu-switching-pools would
exist at the initial device connection
- manage reception of device notification whose target is
odu-switching-pools and port-list in DeviceListener710 class

JIRA: TRNSPRTPCE-405
Signed-off-by: Gilles Thouenon <gilles.thouenon@orange.com>
Change-Id: Ieb7dd5f2a301feb4543c96c3502007012e98db57

common/src/main/java/org/opendaylight/transportpce/common/mapping/PortMapping.java
common/src/main/java/org/opendaylight/transportpce/common/mapping/PortMappingImpl.java
common/src/main/java/org/opendaylight/transportpce/common/mapping/PortMappingVersion710.java
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener710.java

index 89a76a2db112a0e01a7b04171bf0c6e4d178d4d3..8b04bd5ca2cbd82aefc9fb16cc18fa8995b56065 100644 (file)
@@ -8,9 +8,17 @@
 
 package org.opendaylight.transportpce.common.mapping;
 
+
+import java.util.List;
+import java.util.Map;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mapping.Mapping;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mc.capabilities.McCapabilities;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.Nodes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.OduSwitchingPools;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.odu.switching.pools.non.blocking.list.PortList;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint16;
+
 
 public interface PortMapping {
 
@@ -151,4 +159,25 @@ public interface PortMapping {
      * @return node data if success otherwise null.
      */
     Nodes getNode(String nodeId);
+
+    /**
+     * This method allows to update a port-mapping node with odu-connection-map data.
+     * This method is used for an otn xponder in version 7.1, when a device sends a
+     * change-notification advertising controller that odu-switching-pools containers
+     * have been populated inside its configuration
+     * (appears after creation of an OTSI-Group interface).
+     *
+     * @param nodeId
+     *            Unique Identifier for the node of interest.
+     * @param ospIID
+     *            Instance Identifier of the odu-switching-pools.
+     * @param nbliidMap
+     *            Map containing the non-blocking-list number as key,
+     *            and the list of Instance Identifier corresponding to each port-list
+     *            as value.
+     *
+     * @return Result true/false based on status of operation.
+     */
+    boolean updatePortMappingWithOduSwitchingPools(String nodeId, InstanceIdentifier<OduSwitchingPools> ospIID,
+        Map<Uint16, List<InstanceIdentifier<PortList>>> nbliidMap);
 }
index 963fb6a42bbdca28c19c457146c76c33352d3c5c..c19848d4cc83719e99c09c8f27daae77ce65bc1d 100644 (file)
@@ -11,6 +11,7 @@ import static org.opendaylight.transportpce.common.StringConstants.OPENROADM_DEV
 import static org.opendaylight.transportpce.common.StringConstants.OPENROADM_DEVICE_VERSION_2_2_1;
 import static org.opendaylight.transportpce.common.StringConstants.OPENROADM_DEVICE_VERSION_7_1;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ExecutionException;
@@ -28,8 +29,11 @@ import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmappi
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mc.capabilities.McCapabilitiesKey;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.Nodes;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.NodesKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.OduSwitchingPools;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.odu.switching.pools.non.blocking.list.PortList;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -186,4 +190,18 @@ public class PortMappingImpl implements PortMapping {
         }
         return null;
     }
+
+    @Override
+    public boolean updatePortMappingWithOduSwitchingPools(String nodeId, InstanceIdentifier<OduSwitchingPools> ospIID,
+            Map<Uint16, List<InstanceIdentifier<PortList>>> nbliidMap) {
+        OpenroadmNodeVersion openROADMversion = getNode(nodeId).getNodeInfo().getOpenroadmVersion();
+        switch (openROADMversion.getIntValue()) {
+            case 3:
+                return portMappingVersion710.updatePortMappingWithOduSwitchingPools(nodeId, ospIID, nbliidMap);
+            default:
+                LOG.error("Update of the port-mapping [odu-switching-pool] not available for this device version {}",
+                    openROADMversion);
+                return false;
+        }
+    }
 }
index 6b9030e7a08aa28ef873ccd5d179508da9b2298a..8e580ea3e7f595851654ad7cef7cd45cdd466c82 100644 (file)
@@ -23,6 +23,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
 import org.opendaylight.mdsal.binding.api.WriteTransaction;
 import org.opendaylight.mdsal.common.api.CommitInfo;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
@@ -98,6 +99,7 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.port.capability.rev200529
 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.capability.rev200529.port.capability.grp.port.capabilities.supported._interface.capability.otn.capability.MpdrClientRestriction;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
@@ -214,6 +216,76 @@ public class PortMappingVersion710 {
         }
     }
 
+    public boolean updatePortMappingWithOduSwitchingPools(String nodeId, InstanceIdentifier<OduSwitchingPools> ospIID,
+            Map<Uint16, List<InstanceIdentifier<PortList>>> nbliidMap) {
+
+        KeyedInstanceIdentifier<Nodes, NodesKey> portMappingNodeIID = InstanceIdentifier.create(Network.class)
+            .child(Nodes.class, new NodesKey(nodeId));
+        Nodes portmappingNode = null;
+        try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
+            portmappingNode = readTx.read(LogicalDatastoreType.CONFIGURATION, portMappingNodeIID).get().get();
+        } catch (InterruptedException | ExecutionException ex) {
+            LOG.error("Unable to read the port-mapping for nodeId {}", nodeId, ex);
+        }
+        if (portmappingNode == null) {
+            return false;
+        }
+        Map<MappingKey, Mapping> mappings = portmappingNode.nonnullMapping();
+
+        OduSwitchingPools osp = deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL,
+            ospIID, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT).get();
+        Uint16 ospNumber = osp.getSwitchingPoolNumber();
+        Map<SwitchingPoolLcpKey, SwitchingPoolLcp> splMap = new HashMap(portmappingNode.nonnullSwitchingPoolLcp());
+        SwitchingPoolLcpBuilder splBldr = splMap.containsKey(new SwitchingPoolLcpKey(ospNumber))
+            ? new SwitchingPoolLcpBuilder(splMap.get(new SwitchingPoolLcpKey(ospNumber)))
+            : new SwitchingPoolLcpBuilder().setSwitchingPoolNumber(ospNumber)
+                .setSwitchingPoolType(osp.getSwitchingPoolType());
+        Map<NonBlockingListKey, NonBlockingList> nblMap = new HashMap<>();
+        for (Entry<Uint16, List<InstanceIdentifier<PortList>>> entry : nbliidMap.entrySet()) {
+            Uint32 interconnectBw = osp.getNonBlockingList().get(new
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org
+                    .openroadm.device.odu.switching.pools.NonBlockingListKey(entry.getKey()))
+                .getInterconnectBandwidth();
+            NonBlockingList nbl = createNonBlockingList(splBldr, interconnectBw, entry, mappings, nodeId);
+            if (nbl == null) {
+                return false;
+            }
+            nblMap.put(nbl.key(), nbl);
+        }
+        SwitchingPoolLcp switchingPoolLcp = splBldr
+            .setNonBlockingList(nblMap)
+            .build();
+        splMap.put(switchingPoolLcp.key(), switchingPoolLcp);
+        List<SwitchingPoolLcp> switchingPoolList = new ArrayList<>(splMap.values());
+        postPortMapping(nodeId, null, null, null, switchingPoolList, null);
+        return true;
+    }
+
+    private NonBlockingList createNonBlockingList(SwitchingPoolLcpBuilder splBldr, Uint32 interconnectBw,
+            Entry<Uint16, List<InstanceIdentifier<PortList>>> entry, Map<MappingKey, Mapping> mappings, String nodeId) {
+        NonBlockingListBuilder nblBldr;
+        if (splBldr.getNonBlockingList() != null
+            && splBldr.getNonBlockingList().containsKey(new NonBlockingListKey(entry.getKey()))) {
+            nblBldr = new NonBlockingListBuilder(splBldr.getNonBlockingList()
+                .get(new NonBlockingListKey(entry.getKey())));
+        } else {
+            nblBldr = new NonBlockingListBuilder()
+                .setNblNumber(entry.getKey())
+                .setInterconnectBandwidth(interconnectBw);
+        }
+        List<String> lcpList = nblBldr.getLcpList() != null ? nblBldr.getLcpList() : new ArrayList<>();
+        for (InstanceIdentifier<PortList> id : entry.getValue()) {
+            PortList portList = deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL,
+                id, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT).get();
+            String lcp = getLcpFromCpAndPort(mappings, portList.getCircuitPackName(), portList.getPortName());
+            if (lcp == null || lcpList.contains(lcp)) {
+                return null;
+            }
+            lcpList.add(lcp);
+        }
+        return nblBldr.setLcpList(lcpList).build();
+    }
+
     private boolean createXpdrPortMapping(String nodeId, List<Mapping> portMapList) {
         // Creating for Xponder Line and Client Ports
         InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
@@ -1315,4 +1387,13 @@ public class PortMappingVersion710 {
         return nodeInfoBldr.build();
     }
 
+    private String getLcpFromCpAndPort(Map<MappingKey, Mapping> mappings, String cpName, String portName) {
+        for (Mapping mapping : mappings.values()) {
+            if (cpName.equals(mapping.getSupportingCircuitPackName())
+                && portName.equals(mapping.getSupportingPort())) {
+                return mapping.getLogicalConnectionPoint();
+            }
+        }
+        return null;
+    }
 }
index dceb741d61ea3572148788638dbf09f927ef12c0..79cd17d3dee7f0bd377b0f11aa33a736a5940419 100644 (file)
@@ -8,8 +8,11 @@
 
 package org.opendaylight.transportpce.networkmodel.listeners;
 
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 import org.opendaylight.transportpce.common.mapping.PortMapping;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mapping.Mapping;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.ChangeNotification;
@@ -19,8 +22,12 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.OtdrScan
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.change.notification.Edit;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.pack.Ports;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.packs.CircuitPacks;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.OduSwitchingPools;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.odu.switching.pools.NonBlockingList;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.odu.switching.pools.non.blocking.list.PortList;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.common.Uint16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,16 +50,19 @@ public class DeviceListener710 implements OrgOpenroadmDeviceListener {
      */
     @Override
     public void onChangeNotification(ChangeNotification notification) {
+        LOG.debug("device71 notification received = {}", notification);
         if (notification.getEdit() == null) {
             LOG.warn("unable to handle {} notificatin received - list of edit is null", ChangeNotification.QNAME);
             return;
         }
+        Map<Uint16, List<InstanceIdentifier<PortList>>> nbliidMap = new HashMap<>();
+        InstanceIdentifier<OduSwitchingPools> ospIID = null;
         for (Edit edit : notification.getEdit()) {
             // 1. Detect the org-openroadm-device object modified
+            LinkedList<PathArgument> path = new LinkedList<>();
             switch (edit.getTarget().getTargetType().getSimpleName()) {
                 case "Ports":
-                    LinkedList<PathArgument> path = new LinkedList<>();
-                    path.addAll((Collection<? extends PathArgument>) edit.getTarget().getPathArguments());
+                    edit.getTarget().getPathArguments().forEach(p -> path.add(p));
                     InstanceIdentifier<Ports> portIID = (InstanceIdentifier<Ports>) InstanceIdentifier
                         .create(path);
                     String portName = InstanceIdentifier.keyOf(portIID).getPortName();
@@ -76,11 +86,40 @@ public class DeviceListener710 implements OrgOpenroadmDeviceListener {
                     Thread thread = new Thread(handleNetconfEvent);
                     thread.start();
                     break;
+                case "OduSwitchingPools":
+                    LOG.info("odu-switching-pools modified on device {}", nodeId);
+                    edit.getTarget().getPathArguments().forEach(p -> path.add(p));
+                    ospIID = (InstanceIdentifier<OduSwitchingPools>) InstanceIdentifier.create(path);
+                    break;
+                case "PortList":
+                    edit.getTarget().getPathArguments().forEach(p -> path.add(p));
+                    InstanceIdentifier<PortList> plIID = (InstanceIdentifier<PortList>) InstanceIdentifier.create(path);
+                    path.removeLast();
+                    InstanceIdentifier<NonBlockingList> nblIID =
+                        (InstanceIdentifier<NonBlockingList>) InstanceIdentifier.create(path);
+                    Uint16 nblNb = InstanceIdentifier.keyOf(nblIID).getNblNumber();
+                    List<InstanceIdentifier<PortList>> iidList = nbliidMap.containsKey(nblNb)
+                        ? nbliidMap.get(nblNb) : new ArrayList<>();
+                    iidList.add(plIID);
+                    nbliidMap.put(nblNb, iidList);
+                    break;
                 default:
                     LOG.debug("modification of type {} not managed yet", edit.getTarget().getTargetType());
                     break;
             }
         }
+        if (!nbliidMap.isEmpty() && ospIID != null) {
+            InstanceIdentifier<OduSwitchingPools> id = ospIID;
+            Runnable handleNetconfEvent = new Runnable() {
+                @Override
+                public void run() {
+                    portMapping.updatePortMappingWithOduSwitchingPools(nodeId, id, nbliidMap);
+                    LOG.info("{} : swiching-pool data updated", nodeId);
+                }
+            };
+            Thread thread = new Thread(handleNetconfEvent);
+            thread.start();
+        }
     }
 
     @Override