Improve OpenRoadmOtnTopology and add Junit tests 72/90372/8
authorGilles Thouenon <gilles.thouenon@orange.com>
Fri, 5 Jun 2020 10:28:11 +0000 (12:28 +0200)
committerguillaume.lambert <guillaume.lambert@orange.com>
Fri, 12 Jun 2020 08:36:15 +0000 (10:36 +0200)
JIRA: TRNSPRTPCE-270
Signed-off-by: Gilles Thouenon <gilles.thouenon@orange.com>
Co-authored-by: Christophe Betoule <christophe.betoule@orange.com>
Change-Id: I6c1347daa149adce1130c9ccf01b05d7e874ff14

networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopology.java
networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopologyTest.java [new file with mode: 0644]
networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/util/test/JsonUtil.java [new file with mode: 0644]
networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/util/test/NetworkmodelTestUtil.java
networkmodel/src/test/resources/portMapping.json [new file with mode: 0644]

index eced2aeab5c9f559c2238f32b3a4ebd94a69a542..69376befeccfd8b28ed497217067a732e906492c 100644 (file)
@@ -155,23 +155,24 @@ public final class OpenRoadmOtnTopology {
     public static TopologyShard updateOtnLinks(List<Link> suppOdu4Links, List<TerminationPoint> oldTps,
         String serviceRate, Short tribPortNb, Short tribSoltNb, boolean isDeletion) {
         List<Link> links = new ArrayList<>();
+        Long bwIncr = 10000L;
+        if ("1G".equals(serviceRate)) {
+            bwIncr = 1000L;
+        }
         for (Link link : suppOdu4Links) {
             if (link.augmentation(Link1.class) != null && link.augmentation(Link1.class).getAvailableBandwidth() != null
                 && link.augmentation(Link1.class).getUsedBandwidth() != null) {
-                Long avlBwIncr = 10000L;
-                Long usedBwIncr = 10000L;
-                if ("1G".equals(serviceRate)) {
-                    avlBwIncr = 1000L;
-                    usedBwIncr = 1000L;
-                }
                 Uint32 avlBw = link.augmentation(Link1.class).getAvailableBandwidth();
                 Uint32 usedBw = link.augmentation(Link1.class).getUsedBandwidth();
+                if (avlBw.toJava() < bwIncr) {
+                    bwIncr = 0L;
+                }
                 if (isDeletion) {
-                    links.add(updateOtnLinkBwParameters(link, avlBw.toJava() + avlBwIncr,
-                        usedBw.toJava() - usedBwIncr));
+                    links.add(updateOtnLinkBwParameters(link, avlBw.toJava() + bwIncr,
+                        usedBw.toJava() - bwIncr));
                 } else {
-                    links.add(updateOtnLinkBwParameters(link, avlBw.toJava() - avlBwIncr,
-                        usedBw.toJava() + usedBwIncr));
+                    links.add(updateOtnLinkBwParameters(link, avlBw.toJava() - bwIncr,
+                        usedBw.toJava() + bwIncr));
                 }
             } else {
                 LOG.error("Error with otn parameters of supported link {}", link.getLinkId().getValue());
@@ -179,11 +180,14 @@ public final class OpenRoadmOtnTopology {
         }
         List<TerminationPoint> tps = new ArrayList<>();
         for (TerminationPoint tp : oldTps) {
-            tps.add(updateNodeTpTsPool(tp, serviceRate, tribPortNb, tribSoltNb, isDeletion));
+            if (bwIncr != 0) {
+                tps.add(updateNodeTpTsPool(tp, serviceRate, tribPortNb, tribSoltNb, isDeletion));
+            }
         }
         if (!links.isEmpty() && !tps.isEmpty()) {
             return new TopologyShard(null, links, tps);
         } else {
+            LOG.error("unable to update otn links");
             return new TopologyShard(null, null, null);
         }
     }
@@ -215,7 +219,6 @@ public final class OpenRoadmOtnTopology {
             = new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1Builder()
             .setOtnLinkType(linkType).build();
         Link1 otnLink1 = new Link1Builder()
-            .setLinkType(OpenroadmLinkType.OTNLINK)
             .setAvailableBandwidth(Uint32.valueOf(100000))
             .setUsedBandwidth(Uint32.valueOf(0))
             .build();
@@ -230,15 +233,29 @@ public final class OpenRoadmOtnTopology {
             nodeZTopo = nodeZ + "-" + tpZ.split("-")[0];
         }
         LinkBuilder ietfLinkAZBldr = TopologyUtils.createLink(nodeATopo, nodeZTopo, tpA, tpZ, linkIdPrefix);
-        ietfLinkAZBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class,
-            tpceLink1)
-            .addAugmentation(Link1.class, otnLink1);
+        ietfLinkAZBldr
+            .addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class, tpceLink1)
+            .addAugmentation(Link1.class, otnLink1)
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class,
+                new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1Builder(
+                        ietfLinkAZBldr.augmentation(
+                            org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class))
+                    .setLinkType(OpenroadmLinkType.OTNLINK)
+                    .build());
         links.add(ietfLinkAZBldr.build());
         // create link Z-A
         LinkBuilder ietfLinkZABldr = TopologyUtils.createLink(nodeZTopo, nodeATopo, tpZ, tpA, linkIdPrefix);
-        ietfLinkZABldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class,
-            tpceLink1)
-            .addAugmentation(Link1.class, otnLink1);
+        ietfLinkZABldr
+            .addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class, tpceLink1)
+            .addAugmentation(Link1.class, otnLink1)
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class,
+                new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1Builder(
+                        ietfLinkZABldr.augmentation(
+                            org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class))
+                    .setLinkType(OpenroadmLinkType.OTNLINK)
+                    .build());
         links.add(ietfLinkZABldr.build());
         return links;
     }
diff --git a/networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopologyTest.java b/networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopologyTest.java
new file mode 100644 (file)
index 0000000..475c885
--- /dev/null
@@ -0,0 +1,967 @@
+/*
+ * Copyright © 2020 Orange Labs, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.transportpce.networkmodel.util;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.gson.stream.JsonReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
+import org.opendaylight.transportpce.networkmodel.util.test.JsonUtil;
+import org.opendaylight.transportpce.networkmodel.util.test.NetworkmodelTestUtil;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.Network;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.Nodes;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.NodesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.Mapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.MappingBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.NodeInfoBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.NodeTypes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODU2e;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.networks.network.node.SwitchingPools;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If100GE;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If100GEODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If10GEODU2e;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.IfOCHOTU4ODU4;
+import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType;
+import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNode;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class OpenRoadmOtnTopologyTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmOtnTopologyTest.class);
+    private Nodes portMappingTpdr;
+    private Nodes portMappingSpdr;
+    private Nodes portMappingBad;
+
+    public OpenRoadmOtnTopologyTest() {
+        try (Reader reader = new FileReader("src/test/resources/portMapping.json");
+                JsonReader portMappingReader = new JsonReader(reader)) {
+            Network portMapping = (Network) JsonUtil.getInstance().getDataObjectFromJson(portMappingReader,
+                    QName.create("http://org/opendaylight/transportpce/portmapping", "2020-04-29", "network"));
+            for (Nodes nodes : portMapping.getNodes()) {
+                if (nodes.getNodeId().equals("XPDR-A1")) {
+                    this.portMappingTpdr = nodes;
+                } else {
+                    this.portMappingSpdr = nodes;
+                }
+            }
+            List<Mapping> mappingList = new ArrayList<>();
+            mappingList.add(new MappingBuilder().setLogicalConnectionPoint("XPDR0-NETWORK0").build());
+            this.portMappingBad = new NodesBuilder()
+                .setNodeId(this.portMappingTpdr.getNodeId())
+                .setNodeInfo(new NodeInfoBuilder(this.portMappingTpdr.getNodeInfo()).setNodeType(NodeTypes.Ila).build())
+                .setMapping(mappingList)
+                .build();
+            LOG.info("tpdr portMapping = {}", this.portMappingTpdr.toString());
+            LOG.info("spdr portMapping = {}", this.portMappingSpdr.toString());
+            LOG.info("ila portMapping = {}", this.portMappingBad.toString());
+        } catch (IOException e) {
+            LOG.error("Cannot init OpenRoadmOtnTopologyTest ", e);
+            fail("Cannot init OpenRoadmOtnTopologyTest ");
+        }
+    }
+
+    @Test
+    public void createTopologyShardForTpdrTest() {
+        TopologyShard topologyShard = OpenRoadmOtnTopology.createTopologyShard(this.portMappingTpdr);
+        assertNotNull("TopologyShard should never be null", topologyShard);
+        assertEquals("Should contain a single node", 1, topologyShard.getNodes().size());
+        assertEquals("Should contain no link", 0, topologyShard.getLinks().size());
+        Node node = topologyShard.getNodes().get(0);
+        assertEquals("XPDR-A1-XPDR1", node.getNodeId().getValue());
+        // tests supporting nodes
+        List<SupportingNode> supportingNodes = node.getSupportingNode().stream()
+            .sorted((sn1, sn2) -> sn1.getNetworkRef().getValue().compareTo(sn2.getNetworkRef().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("Should contain 3 supporting nodes", 3, supportingNodes.size());
+        assertEquals("clli-network", supportingNodes.get(0).getNetworkRef().getValue());
+        assertEquals("NodeA", supportingNodes.get(0).getNodeRef().getValue());
+        assertEquals("openroadm-network", supportingNodes.get(1).getNetworkRef().getValue());
+        assertEquals("XPDR-A1", supportingNodes.get(1).getNodeRef().getValue());
+        assertEquals("openroadm-topology", supportingNodes.get(2).getNetworkRef().getValue());
+        assertEquals("XPDR-A1-XPDR1", supportingNodes.get(2).getNodeRef().getValue());
+        assertEquals(OpenroadmNodeType.TPDR, node.augmentation(Node1.class).getNodeType());
+        assertEquals(
+            Uint16.valueOf(1),
+            node.augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1.class)
+                .getXpdrAttributes()
+                .getXpdrNumber());
+        //tests list of TPs
+        List<TerminationPoint> tps = node.augmentation(
+                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class)
+            .getTerminationPoint().stream()
+            .sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("node should contain 4 TPs", 4, tps.size());
+        //tests client tp
+        assertEquals("XPDR1-CLIENT1", tps.get(0).getTpId().getValue());
+        assertEquals(
+            "XPDR1-NETWORK1",
+            tps.get(0).augmentation(TerminationPoint1.class).getAssociatedConnectionMapPort());
+        assertEquals(
+            "only If100GE interface capabitily expected",
+            1,
+            tps.get(0).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getTpSupportedInterfaces()
+                .getSupportedInterfaceCapability()
+                .size());
+        assertEquals(
+            If100GE.class.getName(),
+            tps.get(0).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getTpSupportedInterfaces().getSupportedInterfaceCapability()
+                .get(0).getIfCapType().getName());
+        assertEquals(
+            "first TP must be of type client",
+            OpenroadmTpType.XPONDERCLIENT,
+            tps.get(0).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130
+                        .TerminationPoint1.class)
+                .getTpType());
+        //tests network tp
+        assertEquals("XPDR1-NETWORK1", tps.get(2).getTpId().getValue());
+        assertEquals(
+            "XPDR1-CLIENT1",
+            tps.get(2).augmentation(TerminationPoint1.class).getAssociatedConnectionMapPort());
+        assertEquals(
+            "only IfOCHOTU4ODU4 interface capabitily expected",
+            1,
+            tps.get(2).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getTpSupportedInterfaces()
+                .getSupportedInterfaceCapability()
+                .size());
+        assertEquals(
+            IfOCHOTU4ODU4.class.getName(),
+            tps.get(2).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getTpSupportedInterfaces()
+                .getSupportedInterfaceCapability()
+                .get(0)
+                .getIfCapType()
+                .getName());
+        assertEquals(
+            "the rate should be ODU4",
+            ODU4.class.getName(),
+            tps.get(2).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getRate()
+                .getName());
+        assertEquals(
+            "third TP must be of type network",
+            OpenroadmTpType.XPONDERNETWORK,
+            tps.get(2).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1.class)
+                .getTpType());
+    }
+
+    @Test
+    public void createTopologyShardForSpdrTest() {
+        TopologyShard topologyShard = OpenRoadmOtnTopology.createTopologyShard(this.portMappingSpdr);
+        assertNotNull("TopologyShard should never be null", topologyShard);
+        assertEquals("Should contain two nodes", 2, topologyShard.getNodes().size());
+        assertEquals("Should contain no link", 0, topologyShard.getLinks().size());
+        List<Node> nodes = topologyShard.getNodes().stream()
+            .sorted((n1, n2) -> n1.getNodeId().getValue().compareTo(n2.getNodeId().getValue()))
+            .collect(Collectors.toList());
+        for (Node node : nodes) {
+            checkSpdrNode(node);
+        }
+    }
+
+    @Test
+    public void createOtnLinksForOTU4NormalTest() {
+        String nodeA = "SPDRA";
+        String tpA = "XPDR1-NETWORK1";
+        String nodeZ = "SPDRZ";
+        String tpZ = "XPDR1-NETWORK1";
+        List<Link> links = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, OtnLinkType.OTU4).getLinks();
+        assertEquals("2 OTU4 links should have been created", 2, links.size());
+        List<Link> sortedLinks = links.stream()
+            .sorted((l1, l2) -> l1.getLinkId().getValue().compareTo(l2.getLinkId().getValue()))
+            .collect(Collectors.toList());
+        assertEquals(
+            "name of OTU4 linkid AZ",
+            "OTU4-SPDRA-XPDR1-XPDR1-NETWORK1toSPDRZ-XPDR1-XPDR1-NETWORK1",
+            sortedLinks.get(0).getLinkId().getValue());
+        assertEquals(
+            "name of OTU4 linkid ZA",
+            "OTU4-SPDRZ-XPDR1-XPDR1-NETWORK1toSPDRA-XPDR1-XPDR1-NETWORK1",
+            sortedLinks.get(1).getLinkId().getValue());
+        assertEquals("SPDRA-XPDR1", sortedLinks.get(0).getSource().getSourceNode().getValue());
+        assertEquals("SPDRZ-XPDR1", sortedLinks.get(0).getDestination().getDestNode().getValue());
+        assertEquals("SPDRZ-XPDR1", sortedLinks.get(1).getSource().getSourceNode().getValue());
+        assertEquals("SPDRA-XPDR1", sortedLinks.get(1).getDestination().getDestNode().getValue());
+        assertEquals(
+            "available BW at OTU4 creation should be 100G (100000)",
+            Uint32.valueOf(100000),
+            sortedLinks.get(0).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "used BW at OTU4 creation should be 0",
+            Uint32.valueOf(0),
+            sortedLinks.get(0).augmentation(Link1.class).getUsedBandwidth());
+        assertEquals(
+            OpenroadmLinkType.OTNLINK,
+            sortedLinks.get(0).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class)
+                .getLinkType());
+        assertEquals(
+            "opposite link must be present",
+            "OTU4-SPDRZ-XPDR1-XPDR1-NETWORK1toSPDRA-XPDR1-XPDR1-NETWORK1",
+            sortedLinks.get(0).augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class)
+                .getOppositeLink()
+                .getValue());
+        assertEquals(
+            "otn link type should be OTU4",
+            OtnLinkType.OTU4,
+            sortedLinks.get(0).augmentation(
+                    org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class)
+                .getOtnLinkType());
+    }
+
+    @Test
+    public void createOtnLinksForNotManagedOtnlinktypeTest() {
+        String nodeA = "SPDRA";
+        String tpA = "XPDR1-NETWORK1";
+        String nodeZ = "SPDRZ";
+        String tpZ = "XPDR1-NETWORK1";
+        TopologyShard topoShard = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, OtnLinkType.ODU0);
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("TopologyShard should not contain any node", topoShard.getNodes());
+        assertNull("TopologyShard should not contain any link", topoShard.getLinks());
+    }
+
+    @Test
+    public void createOtnLinksForODU4NormalTest() {
+        TopologyShard topoShard = OpenRoadmOtnTopology
+            .createOtnLinks(
+                NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.OTU4, 100000),
+                NetworkmodelTestUtil.createTpList(false));
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        List<Link> sortedLinks = topoShard.getLinks().stream()
+            .sorted((l1, l2) -> l1.getLinkId().getValue().compareTo(l2.getLinkId().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("list of links should contain 4 links", 4, sortedLinks.size());
+        assertTrue("link 3 should be of type OTU4", sortedLinks.get(2).getLinkId().getValue().startsWith("OTU4-"));
+        assertEquals(
+            "after odu4 creation, available BW of supported OTU4 should be 0",
+            Uint32.valueOf(0),
+            sortedLinks.get(2).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "after odu4 creation, used BW of supported OTU4 should be 100 000",
+            Uint32.valueOf(100000),
+            sortedLinks.get(2).augmentation(Link1.class).getUsedBandwidth());
+
+        assertEquals(
+            "ODU4-SPDRA-XPDR1-XPDR1-NETWORK1toSPDRZ-XPDR1-XPDR1-NETWORK1",
+            sortedLinks.get(0).getLinkId().getValue());
+        assertEquals(
+            "ODU4-SPDRZ-XPDR1-XPDR1-NETWORK1toSPDRA-XPDR1-XPDR1-NETWORK1",
+            sortedLinks.get(1).getLinkId().getValue());
+        assertEquals("SPDRA-XPDR1", sortedLinks.get(0).getSource().getSourceNode().getValue());
+        assertEquals("SPDRZ-XPDR1", sortedLinks.get(0).getDestination().getDestNode().getValue());
+        assertEquals("SPDRZ-XPDR1", sortedLinks.get(1).getSource().getSourceNode().getValue());
+        assertEquals("SPDRA-XPDR1", sortedLinks.get(1).getDestination().getDestNode().getValue());
+        assertEquals(
+            "after odu4 creation, its available BW should be 100 000",
+            Uint32.valueOf(100000),
+            sortedLinks.get(0).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "after odu4 creation, its used BW should be 0",
+            Uint32.valueOf(0),
+            sortedLinks.get(0).augmentation(Link1.class).getUsedBandwidth());
+        assertEquals(
+            OpenroadmLinkType.OTNLINK,
+            sortedLinks.get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class)
+                .getLinkType());
+        assertEquals(
+            "opposite link must be present",
+            "ODU4-SPDRZ-XPDR1-XPDR1-NETWORK1toSPDRA-XPDR1-XPDR1-NETWORK1",
+            sortedLinks.get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class)
+                .getOppositeLink()
+                .getValue());
+        assertEquals(
+            "otn link type should be ODTU4",
+            OtnLinkType.ODTU4,
+            sortedLinks.get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class)
+                .getOtnLinkType());
+
+        assertEquals("list of TPs should contain 2 updated TPs", 2, topoShard.getTps().size());
+        assertNotNull(
+            "after ODU4 creation, its termination point should contain a TsPool list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool());
+        assertEquals(
+            "Ts pool list should be full, with 80 trib slots",
+            80,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool()
+                .size());
+        assertNotNull(
+            "after ODU4 creation, its termination point should contain a TpnPool list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool());
+        assertEquals(
+            "Tpn pool list should be full, with 80 trib ports",
+            80,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool()
+                .size());
+    }
+
+    @Test
+    public void createOtnLinksForODU4WhenOTU4HaveBadBWParamsTest() {
+        List<Link> otu4Links = NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.OTU4, 100000);
+        List<Link> otu4LinksWithBadBWParam = new ArrayList<>();
+        for (Link link : otu4Links) {
+            otu4LinksWithBadBWParam.add(new LinkBuilder(link).removeAugmentation(Link1.class).build());
+        }
+        TopologyShard topoShard =
+            OpenRoadmOtnTopology.createOtnLinks(otu4LinksWithBadBWParam, NetworkmodelTestUtil.createTpList(false));
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        assertNull("list of links should be null", topoShard.getLinks());
+        assertNull("list of tps should be null", topoShard.getTps());
+
+        otu4LinksWithBadBWParam.clear();
+        topoShard =
+            OpenRoadmOtnTopology.createOtnLinks(
+                    NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.OTU4, 99000),
+                    NetworkmodelTestUtil.createTpList(false));
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        assertNull("list of links should be null", topoShard.getLinks());
+        assertNull("list of tps should be null", topoShard.getTps());
+    }
+
+    @Test
+    public void deleteOtnLinksForODU4NormalTest() {
+        TopologyShard topoShard =
+            OpenRoadmOtnTopology.deleteOtnLinks(
+                    NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.OTU4, 0),
+                    NetworkmodelTestUtil.createTpList(true));
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertEquals("list of links should contain 2 links", 2, topoShard.getLinks().size());
+        assertEquals(
+            "after ODU4 deletion, available BW of supported OTU4 should be 100 000",
+            Uint32.valueOf(100000),
+            topoShard.getLinks().get(0).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "after ODU4 deletion, used BW of supported OTU4 should be 0",
+            Uint32.valueOf(0),
+            topoShard.getLinks().get(0).augmentation(Link1.class).getUsedBandwidth());
+
+        assertEquals("list of TPs should contain 2 updated TPs", 2, topoShard.getTps().size());
+        assertNull(
+            "after ODU4 deletion, its termination points should not contain any TsPool list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool());
+        assertNull(
+            "after ODU4 deletion, its termination points should not contain any TpnPool list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool());
+    }
+
+    @Test
+    public void deleteOtnLinksForODU4WhenOTU4HaveBadBWParamsTest() {
+        List<Link> otu4Links = NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.OTU4, 0);
+        List<Link> otu4LinksWithBadBWParam = new ArrayList<>();
+        for (Link link : otu4Links) {
+            otu4LinksWithBadBWParam.add(new LinkBuilder(link).removeAugmentation(Link1.class).build());
+        }
+        TopologyShard topoShard =
+            OpenRoadmOtnTopology.deleteOtnLinks(otu4LinksWithBadBWParam, NetworkmodelTestUtil.createTpList(true));
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        assertNull("list of links should be null", topoShard.getLinks());
+        assertNull("list of tps should be null", topoShard.getTps());
+    }
+
+    @Test
+    public void updateOtnLinksFor10GTest() {
+        // tests update for 10G creation
+        TopologyShard topoShard =
+            OpenRoadmOtnTopology.updateOtnLinks(
+                    NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.ODTU4, 100000),
+                    NetworkmodelTestUtil.createTpList(true),
+                    "10G", (short)1, (short)1, false);
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        List<Link> sortedLinks = topoShard.getLinks().stream()
+            .sorted((l1, l2) -> l1.getLinkId().getValue().compareTo(l2.getLinkId().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("list of links should contain 2 links", 2, sortedLinks.size());
+        assertTrue(sortedLinks.get(0).getLinkId().getValue().startsWith("ODU4-"));
+        assertEquals(
+            "after 10G creation, available BW of supported ODU4 should be 90000",
+            Uint32.valueOf(90000),
+            sortedLinks.get(0).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "after 10G creation, used BW of supported ODU4 should be 10000",
+            Uint32.valueOf(10000),
+            sortedLinks.get(0).augmentation(Link1.class).getUsedBandwidth());
+
+        assertEquals(
+            "after 10G creation, 8 (over 80) trib slot should be occupied",
+            72,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool()
+                .size());
+        assertThat(
+            "trib slot 1-8 should no longer be present in Trib slot list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool(),
+            not(hasItems(Uint16.valueOf(1), Uint16.valueOf(8))));
+        assertThat(
+            "trib slot 9 should always be present in trib slot list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool(),
+            hasItem(Uint16.valueOf(9)));
+        assertEquals(
+            "after 10G creation, 1 (over 80) trib port should be occupied",
+            79,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool()
+                .size());
+        assertThat(
+            "trib port 1 should no longer be present",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool(),
+            not(hasItem(Uint16.valueOf(1))));
+
+        // tests update for 10G deletion
+        sortedLinks.clear();
+        topoShard = OpenRoadmOtnTopology.updateOtnLinks(topoShard.getLinks(), topoShard.getTps(), "10G", (short)1,
+            (short)1, true);
+        sortedLinks = topoShard.getLinks().stream()
+            .sorted((l1, l2) -> l1.getLinkId().getValue().compareTo(l2.getLinkId().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("list of links should contain 2 links", 2, sortedLinks.size());
+        assertTrue(sortedLinks.get(0).getLinkId().getValue().startsWith("ODU4-"));
+        assertEquals(
+            "after 10G deletion, available BW of supported ODU4 should be 100 000",
+            Uint32.valueOf(100000),
+            sortedLinks.get(0).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "after 10G deletion, used BW of supported ODU4 should be 0",
+            Uint32.valueOf(0),
+            sortedLinks.get(0).augmentation(Link1.class).getUsedBandwidth());
+
+        assertEquals(
+            "after 10G deletion, trib slot list should be full",
+            80,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool()
+                .size());
+        assertThat(
+            "after 10G deletion, trib slot list should contain items 1-8",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool(),
+            hasItems(Uint16.valueOf(1), Uint16.valueOf(8), Uint16.valueOf(9)));
+        assertEquals(
+            "after 10G deletion, trib port list should be full",
+                80,
+                topoShard.getTps().get(0)
+                    .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                    .getXpdrTpPortConnectionAttributes()
+                    .getOdtuTpnPool().get(0)
+                    .getTpnPool()
+                    .size());
+        assertThat(
+            "after 10G deletion, trib port list should contain items 1",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool(),
+            hasItem(Uint16.valueOf(1)));
+    }
+
+    @Test
+    public void updateOtnLinksFor1GCreationTest() {
+        // tests update for 1G creation
+        TopologyShard topoShard =
+            OpenRoadmOtnTopology.updateOtnLinks(
+                    NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.ODTU4, 100000),
+                    NetworkmodelTestUtil.createTpList(true),
+                    "1G", (short)1, (short)1, false);
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        List<Link> sortedLinks = topoShard.getLinks().stream()
+            .sorted((l1, l2) -> l1.getLinkId().getValue().compareTo(l2.getLinkId().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("list of links should contain 2 links", 2, sortedLinks.size());
+        assertTrue(sortedLinks.get(0).getLinkId().getValue().startsWith("ODU4-"));
+        assertEquals(
+            "after 1G creation, available BW of supported ODU4 should be 99000",
+            Uint32.valueOf(99000),
+            sortedLinks.get(0).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "after 1G creation, used BW of supported ODU4 should be 1000",
+            Uint32.valueOf(1000),
+            sortedLinks.get(0).augmentation(Link1.class).getUsedBandwidth());
+
+        assertEquals(
+            "after 1G creation, 1 (over 80) trib slot should be occupied",
+            79,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool()
+                .size());
+        assertThat(
+            "trib slot 1 should no longer be present in Trib slot list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool(),
+            not(hasItem(Uint16.valueOf(1))));
+        assertThat(
+            "trib slot 2 should always be present in Trib slot list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes().getTsPool(),
+            hasItem(Uint16.valueOf(2)));
+        assertEquals(
+            "after 1G creation, 1 (over 80) trib port should be occupied",
+            79,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool()
+                .size());
+        assertThat(
+            "trib port 1 should no longer be present in Trib port list",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool(),
+            not(hasItem(Uint16.valueOf(1))));
+
+        // tests update for 1G deletion
+        sortedLinks.clear();
+        topoShard =
+            OpenRoadmOtnTopology.updateOtnLinks(
+                    topoShard.getLinks(),
+                    topoShard.getTps(),
+                    "1G", (short)1, (short)1, true);
+        sortedLinks = topoShard.getLinks().stream()
+            .sorted((l1, l2) -> l1.getLinkId().getValue().compareTo(l2.getLinkId().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("list of links should contain 2 links", 2, sortedLinks.size());
+        assertTrue(sortedLinks.get(0).getLinkId().getValue().startsWith("ODU4-"));
+        assertEquals(
+            "after 1G deletion, available BW of supported ODU4 should be 100 000",
+            Uint32.valueOf(100000),
+            sortedLinks.get(0).augmentation(Link1.class).getAvailableBandwidth());
+        assertEquals(
+            "after 1G deletion, used BW of supported ODU4 should be 0",
+            Uint32.valueOf(0),
+            sortedLinks.get(0).augmentation(Link1.class).getUsedBandwidth());
+
+        assertEquals(
+            "after 1G deletion, trib slot list should be full",
+            80,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool()
+                .size());
+        assertThat(
+            "after 1G deletion, trib slot list should contain items 1 and 2",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                    .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getTsPool(),
+            hasItems(Uint16.valueOf(1), Uint16.valueOf(2)));
+        assertEquals(
+            "after 1G deletion, trib port list should be full",
+            80,
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool()
+                .size());
+        assertThat(
+            "after 1G deletion, trib port list should contain items 1",
+            topoShard.getTps().get(0)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getOdtuTpnPool().get(0)
+                .getTpnPool(),
+            hasItem(Uint16.valueOf(1)));
+    }
+
+    @Test
+    public void updateOtnLinksForODU4WhenBWParamsNotPresentTest() {
+        List<Link> odu4Links = NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.ODTU4, 100000);
+        List<Link> odu4LinksWithBadBWParam = new ArrayList<>();
+        for (Link link : odu4Links) {
+            odu4LinksWithBadBWParam.add(new LinkBuilder(link).removeAugmentation(Link1.class).build());
+        }
+        TopologyShard topoShard =
+            OpenRoadmOtnTopology.updateOtnLinks(
+                    odu4LinksWithBadBWParam,
+                    NetworkmodelTestUtil.createTpList(true),
+                    "1G", (short)1, (short)1, false);
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        assertNull("list of links should be null", topoShard.getLinks());
+        assertNull("list of tps should be null", topoShard.getTps());
+    }
+
+    @Test
+    public void updateOtnLinksForODU4WhenAvailBWNotSufficientTest() {
+        List<Link> odu4LinksWithBadBWParam = NetworkmodelTestUtil.createSuppOTNLinks(OtnLinkType.ODTU4, 8000);
+        TopologyShard topoShard =
+            OpenRoadmOtnTopology.updateOtnLinks(
+                    odu4LinksWithBadBWParam,
+                    NetworkmodelTestUtil.createTpList(true),
+                    "10G", (short)1, (short)1, false);
+        assertNotNull("TopologyShard should never be null", topoShard);
+        assertNull("list of nodes should be null", topoShard.getNodes());
+        assertNull("list of links should be null", topoShard.getLinks());
+        assertNull("list of tps should be null", topoShard.getTps());
+    }
+
+    private void checkSpdrNode(Node node) {
+        Uint16 xpdrNb = node
+            .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1.class)
+            .getXpdrAttributes().getXpdrNumber();
+        assertEquals("SPDR-SA1-XPDR" + xpdrNb, node.getNodeId().getValue());
+        if (xpdrNb.equals(Uint16.valueOf(1))) {
+            assertEquals(OpenroadmNodeType.MUXPDR, node.augmentation(Node1.class).getNodeType());
+        } else if (xpdrNb.equals(Uint16.valueOf(2))) {
+            assertEquals(OpenroadmNodeType.SWITCH, node.augmentation(Node1.class).getNodeType());
+        }
+        // tests supporting nodes
+        List<SupportingNode> supportingNodes = node.getSupportingNode().stream()
+            .sorted((sn1, sn2) -> sn1.getNetworkRef().getValue().compareTo(sn2.getNetworkRef().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("Should contain 3 supporting nodes", 3, supportingNodes.size());
+        assertEquals("clli-network", supportingNodes.get(0).getNetworkRef().getValue());
+        assertEquals("NodeSA", supportingNodes.get(0).getNodeRef().getValue());
+        assertEquals("openroadm-network", supportingNodes.get(1).getNetworkRef().getValue());
+        assertEquals("SPDR-SA1", supportingNodes.get(1).getNodeRef().getValue());
+        assertEquals("openroadm-topology", supportingNodes.get(2).getNetworkRef().getValue());
+        assertEquals("SPDR-SA1-XPDR" + xpdrNb, supportingNodes.get(2).getNodeRef().getValue());
+        checkSpdrSwitchingPools(
+            xpdrNb,
+            node.augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1.class)
+                .getSwitchingPools());
+        List<TerminationPoint> tpList = node.augmentation(
+                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class)
+            .getTerminationPoint().stream()
+            .sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue()))
+            .collect(Collectors.toList());
+        checkSpdrTpList(xpdrNb, tpList);
+    }
+
+    private void checkSpdrSwitchingPools(Uint16 xpdrNb, SwitchingPools sp) {
+        assertEquals(
+            "switching-pools augmentation should contain a single odu-switching-pools",
+            1,
+            sp.getOduSwitchingPools().size());
+        assertEquals(
+            "switching-pool-number should be 1",
+            Uint16.valueOf(1),
+            sp.getOduSwitchingPools().get(0).getSwitchingPoolNumber());
+        assertEquals(
+            "switching-pool-type should be non-blocking",
+            "non-blocking",
+            sp.getOduSwitchingPools().get(0).getSwitchingPoolType().getName());
+        if (xpdrNb.equals(Uint16.valueOf(1))) {
+            assertEquals(
+                "Mux should contain 4 non blocking list",
+                4,
+                sp.getOduSwitchingPools().get(0).getNonBlockingList().size());
+            assertEquals(
+                Uint16.valueOf(1),
+                sp.getOduSwitchingPools().get(0).getNonBlockingList().get(0).getNblNumber());
+            List<NonBlockingList> nblList = sp.getOduSwitchingPools().get(0).getNonBlockingList().stream()
+                .sorted((nbl1, nbl2) -> nbl1.getNblNumber().compareTo(nbl2.getNblNumber()))
+                .collect(Collectors.toList());
+            for (NonBlockingList nbl : nblList) {
+                assertEquals(
+                    "for a 10G mux, interconnect BW should be 10G",
+                    Uint32.valueOf(10),
+                    nbl.getAvailableInterconnectBandwidth());
+                assertEquals(Uint32.valueOf(1000000000), nbl.getInterconnectBandwidthUnit());
+                assertThat(
+                    "for a 10G mux, non blocking list should contain 2 entries (client + network ports)",
+                    nbl.getTpList(),
+                    hasSize(2));
+                String nb = nbl.getNblNumber().toString();
+                assertThat(
+                    nbl.getTpList(),
+                    containsInAnyOrder(new TpId("XPDR1-NETWORK1"),
+                    new TpId("XPDR1-CLIENT" + nb)));
+            }
+        } else if (xpdrNb.equals(Uint16.valueOf(2))) {
+            assertEquals(
+                "Switch should contain a single non blocking list",
+                1,
+                sp.getOduSwitchingPools().get(0).getNonBlockingList().size());
+            assertEquals(
+                Uint16.valueOf(1),
+                sp.getOduSwitchingPools().get(0).getNonBlockingList().get(0).getNblNumber());
+            assertThat(
+                "for a 100G Switch, non blocking list should contain 8 entries (4 clients + 4 network ports)",
+                sp.getOduSwitchingPools().get(0).getNonBlockingList().get(0).getTpList(),
+                hasSize(8));
+            assertThat(
+                sp.getOduSwitchingPools().get(0).getNonBlockingList().get(0).getTpList(),
+                containsInAnyOrder(
+                    new TpId("XPDR2-CLIENT1"), new TpId("XPDR2-NETWORK1"), new TpId("XPDR2-CLIENT2"),
+                    new TpId("XPDR2-NETWORK2"), new TpId("XPDR2-CLIENT3"), new TpId("XPDR2-NETWORK3"),
+                    new TpId("XPDR2-CLIENT4"), new TpId("XPDR2-NETWORK4")));
+        }
+    }
+
+    private void checkSpdrTpList(Uint16 xpdrNb, List<TerminationPoint> tpList) {
+        assertEquals(
+            "only IfOCHOTU4ODU4 interface capabitily expected",
+            IfOCHOTU4ODU4.class,
+            tpList.get(4)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getTpSupportedInterfaces()
+                .getSupportedInterfaceCapability().get(0)
+                .getIfCapType());
+        assertEquals(
+            "the rate should be ODU4",
+            ODU4.class,
+            tpList.get(4)
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                        .TerminationPoint1.class)
+                .getXpdrTpPortConnectionAttributes()
+                .getRate());
+        assertEquals(
+            "openroadm-topology",
+            tpList.get(4).getSupportingTerminationPoint().get(0).getNetworkRef().getValue());
+        assertEquals(
+            "SPDR-SA1-XPDR" + xpdrNb,
+            tpList.get(4).getSupportingTerminationPoint().get(0).getNodeRef().getValue());
+        assertEquals(
+            "XPDR" + xpdrNb + "-NETWORK1",
+            tpList.get(4).getSupportingTerminationPoint().get(0).getTpRef());
+        if (xpdrNb.equals(Uint16.valueOf(1))) {
+            assertEquals("should contain 5 TPs", 5, tpList.size());
+            assertEquals("XPDR1-CLIENT1", tpList.get(0).getTpId().getValue());
+            assertEquals("XPDR1-CLIENT2", tpList.get(1).getTpId().getValue());
+            assertEquals("XPDR1-NETWORK1", tpList.get(4).getTpId().getValue());
+            assertEquals(
+                "only If10GEODU2e interface capabitily expected",
+                If10GEODU2e.class,
+                tpList.get(2)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                            .TerminationPoint1.class)
+                    .getTpSupportedInterfaces()
+                    .getSupportedInterfaceCapability().get(0)
+                    .getIfCapType());
+            assertEquals(
+                "the rate should be ODU2e",
+                ODU2e.class,
+                tpList.get(2)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                            .TerminationPoint1.class)
+                    .getXpdrTpPortConnectionAttributes()
+                    .getRate());
+            assertEquals(
+                "TP should be of type client",
+                OpenroadmTpType.XPONDERCLIENT,
+                tpList.get(2)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130
+                            .TerminationPoint1.class)
+                    .getTpType());
+            assertEquals(
+                "TP should be of type network",
+                OpenroadmTpType.XPONDERNETWORK,
+                tpList.get(4)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130
+                            .TerminationPoint1.class)
+                    .getTpType());
+        } else if (xpdrNb.equals(Uint16.valueOf(2))) {
+            assertEquals("should contain 8 TPs", 8, tpList.size());
+            assertEquals("XPDR2-CLIENT1", tpList.get(0).getTpId().getValue());
+            assertEquals("XPDR2-CLIENT2", tpList.get(1).getTpId().getValue());
+            assertEquals("XPDR2-NETWORK1", tpList.get(4).getTpId().getValue());
+            assertEquals("XPDR2-NETWORK2", tpList.get(5).getTpId().getValue());
+            assertEquals(
+                "only If100GEODU4 interface capabitily expected",
+                If100GEODU4.class,
+                tpList.get(2)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                                .TerminationPoint1.class)
+                    .getTpSupportedInterfaces()
+                    .getSupportedInterfaceCapability().get(0)
+                    .getIfCapType());
+            assertEquals(
+                "the rate should be ODU4",
+                ODU4.class,
+                tpList.get(2)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                            .TerminationPoint1.class)
+                    .getXpdrTpPortConnectionAttributes()
+                    .getRate());
+            assertEquals(
+                "TP should be of type client", OpenroadmTpType.XPONDERCLIENT,
+                tpList.get(2)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130
+                            .TerminationPoint1.class)
+                    .getTpType());
+            assertEquals(
+                "TP should be of type network", OpenroadmTpType.XPONDERNETWORK,
+                tpList.get(6)
+                    .augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130
+                            .TerminationPoint1.class)
+                    .getTpType());
+        }
+    }
+}
diff --git a/networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/util/test/JsonUtil.java b/networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/util/test/JsonUtil.java
new file mode 100644 (file)
index 0000000..e81d6e6
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2020 Orange Labs, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.transportpce.networkmodel.util.test;
+
+import com.google.gson.stream.JsonReader;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ServiceLoader;
+import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
+import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+public final class JsonUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(JsonUtil.class);
+    private static JsonUtil instance;
+
+    private SchemaContext schemaCtx;
+
+    private BindingNormalizedNodeCodecRegistry codecRegistry;
+
+    private JsonUtil() {
+        List<YangModuleInfo> moduleInfos = new LinkedList<>();
+        ServiceLoader<YangModelBindingProvider> yangProviderLoader = ServiceLoader.load(YangModelBindingProvider.class);
+        for (YangModelBindingProvider yangModelBindingProvider : yangProviderLoader) {
+            moduleInfos.add(yangModelBindingProvider.getModuleInfo());
+        }
+        /* Create the schema context for loaded models */
+        ModuleInfoBackedContext moduleInfoBackedCntxt = ModuleInfoBackedContext.create();
+        moduleInfoBackedCntxt.addModuleInfos(moduleInfos);
+        schemaCtx = moduleInfoBackedCntxt.getSchemaContext();
+        if (schemaCtx == null) {
+            throw new IllegalStateException("Failed to load schema context");
+        }
+        // Create the binding binding normalized node codec registry
+        BindingRuntimeContext bindingRuntimeContext = BindingRuntimeContext.create(moduleInfoBackedCntxt, schemaCtx);
+        codecRegistry = new BindingNormalizedNodeCodecRegistry(bindingRuntimeContext);
+    }
+
+    public static JsonUtil getInstance() {
+        if (instance == null) {
+            instance = new JsonUtil();
+        }
+        return instance;
+    }
+
+    public DataObject getDataObjectFromJson(JsonReader reader, QName pathQname) {
+        NormalizedNodeResult result = new NormalizedNodeResult();
+        try (NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+                JsonParserStream jsonParser = JsonParserStream.create(streamWriter,
+                        JSONCodecFactorySupplier.RFC7951.getShared(schemaCtx), schemaCtx);) {
+            jsonParser.parse(reader);
+            YangInstanceIdentifier yangId = YangInstanceIdentifier.of(pathQname);
+            if (codecRegistry.fromNormalizedNode(yangId, result.getResult()) != null) {
+                return codecRegistry.fromNormalizedNode(yangId, result.getResult()).getValue();
+            } else {
+                return null;
+            }
+        } catch (IOException | IllegalArgumentException e) {
+            LOG.error("Cannot deserialize JSON ", e);
+            return null;
+        }
+
+    }
+}
index 90e7d3831bb6b094e73b5f294d52c01e2bea7afb..121c5e2429a52ede1709e86b6e4d2d404d4baf6f 100644 (file)
@@ -7,20 +7,51 @@
  */
 package org.opendaylight.transportpce.networkmodel.util.test;
 
-
+import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.List;
+import org.opendaylight.transportpce.common.NetworkUtils;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.Nodes;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.NodesBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.Mapping;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.MappingBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.NodeInfoBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1Builder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.NodeTypes;
 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.network.types.rev181130.OpenroadmLinkType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.xpdr.tp.supported.interfaces.SupportedInterfaceCapability;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODTU4TsAllocated;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.TerminationPoint1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.networks.network.node.termination.point.TpSupportedInterfaces;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.networks.network.node.termination.point.TpSupportedInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.networks.network.node.termination.point.XpdrTpPortConnectionAttributesBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181019.If100GE;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181019.IfOCH;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181019.SupportedIfCapability;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.IfOCHOTU4ODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev181130.xpdr.otn.tp.attributes.OdtuTpnPoolBuilder;
+import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.SourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPointBuilder;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,6 +84,140 @@ public final class NetworkmodelTestUtil {
         return mappingNode;
     }
 
+    public static List<Link> createSuppOTNLinks(OtnLinkType type, int availBW) {
+        String prefix = null;
+        if (OtnLinkType.OTU4.equals(type)) {
+            prefix = "OTU4-";
+        } else if (OtnLinkType.ODTU4.equals(type)) {
+            prefix = "ODU4-";
+        }
+        Link linkAZ = new LinkBuilder()
+            .setLinkId(new LinkId(prefix + "SPDRA-XPDR1-XPDR1-NETWORK1toSPDRZ-XPDR1-XPDR1-NETWORK1"))
+            .setSource(new SourceBuilder()
+                    .setSourceNode(new NodeId("SPDRA-XPDR1"))
+                    .setSourceTp("XPDR1-NETWORK1").build())
+            .setDestination(new DestinationBuilder()
+                    .setDestNode(new NodeId("SPDRZ-XPDR1"))
+                    .setDestTp("XPDR1-NETWORK1").build())
+            .addAugmentation(
+                Link1.class,
+                new Link1Builder()
+                    .setLinkType(OpenroadmLinkType.OTNLINK)
+                    .setOppositeLink(new LinkId(prefix + "SPDRZ-XPDR1-XPDR1-NETWORK1toSPDRA-XPDR1-XPDR1-NETWORK1"))
+                    .build())
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1.class,
+                new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1Builder()
+                    .setAvailableBandwidth(Uint32.valueOf(availBW))
+                    .setUsedBandwidth(Uint32.valueOf(100000 - availBW))
+                    .build())
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class,
+                new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1Builder()
+                    .setOtnLinkType(type)
+                    .build())
+            .build();
+        Link linkZA = new LinkBuilder()
+            .setLinkId(new LinkId(prefix + "SPDRZ-XPDR1-XPDR1-NETWORK1toSPDRA-XPDR1-XPDR1-NETWORK1"))
+            .setSource(new SourceBuilder()
+                    .setSourceNode(new NodeId("SPDRZ-XPDR1"))
+                    .setSourceTp("XPDR1-NETWORK1").build())
+            .setDestination(new DestinationBuilder()
+                    .setDestNode(new NodeId("SPDRA-XPDR1"))
+                    .setDestTp("XPDR1-NETWORK1").build())
+            .addAugmentation(
+                Link1.class,
+                new Link1Builder()
+                    .setLinkType(OpenroadmLinkType.OTNLINK)
+                    .setOppositeLink(new LinkId(prefix + "SPDRA-XPDR1-XPDR1-NETWORK1toSPDRZ-XPDR1-XPDR1-NETWORK1"))
+                    .build())
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1.class,
+                new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1Builder()
+                    .setAvailableBandwidth(Uint32.valueOf(availBW))
+                    .setUsedBandwidth(Uint32.valueOf(100000 - availBW))
+                    .build())
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class,
+                new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1Builder()
+                    .setOtnLinkType(type)
+                    .build())
+            .build();
+        List<Link> links = new ArrayList<>();
+        links.add(linkAZ);
+        links.add(linkZA);
+        return links;
+    }
+
+    public static List<TerminationPoint> createTpList(boolean withTpnTsPool) {
+        SupportedInterfaceCapability supCapa = new SupportedInterfaceCapabilityBuilder()
+            .setIfCapType(IfOCHOTU4ODU4.class)
+            .build();
+        List<SupportedInterfaceCapability> supInterCapaList = new ArrayList<>();
+        supInterCapaList.add(supCapa);
+        TpSupportedInterfaces tpSuppInter = new TpSupportedInterfacesBuilder()
+            .setSupportedInterfaceCapability(supInterCapaList)
+            .build();
+        XpdrTpPortConnectionAttributesBuilder xtpcaBldr = new XpdrTpPortConnectionAttributesBuilder()
+            .setRate(ODU4.class);
+        if (withTpnTsPool) {
+            List<Uint16> tsPool = new ArrayList<>();
+            for (int i = 0; i < 80; i++) {
+                tsPool.add(Uint16.valueOf(i + 1));
+            }
+            xtpcaBldr.setTsPool(tsPool);
+            List<Uint16> tpnPool = new ArrayList<>();
+            for (int i = 1; i <= 80; i++) {
+                tpnPool.add(Uint16.valueOf(i));
+            }
+            xtpcaBldr.setOdtuTpnPool(
+                    ImmutableList.of(
+                        new OdtuTpnPoolBuilder().setOdtuType(ODTU4TsAllocated.class).setTpnPool(tpnPool).build()));
+        }
+        TerminationPoint1 otnTp1 = new TerminationPoint1Builder()
+            .setTpSupportedInterfaces(tpSuppInter)
+            .setXpdrTpPortConnectionAttributes(xtpcaBldr.build())
+            .build();
+        SupportingTerminationPoint supTermPointA = new SupportingTerminationPointBuilder()
+            .setNetworkRef(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))
+            .setNodeRef(new NodeId("SPDRA-XPDR1"))
+            .setTpRef("XPDR1-NETWORK1")
+            .build();
+        List<SupportingTerminationPoint> supTermPointListA = new ArrayList<>();
+        supTermPointListA.add(supTermPointA);
+        TerminationPoint tpA = new TerminationPointBuilder()
+            .setTpId(new TpId("XPDR1-NETWORK1"))
+            .setSupportingTerminationPoint(supTermPointListA)
+            .addAugmentation(TerminationPoint1.class, otnTp1)
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1.class,
+                new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1Builder()
+                .setTpType(OpenroadmTpType.XPONDERNETWORK)
+                .build())
+            .build();
+        SupportingTerminationPoint supTermPointZ = new SupportingTerminationPointBuilder()
+            .setNetworkRef(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))
+            .setNodeRef(new NodeId("SPDRZ-XPDR1"))
+            .setTpRef("XPDR1-NETWORK1")
+            .build();
+        List<SupportingTerminationPoint> supTermPointListZ = new ArrayList<>();
+        supTermPointListZ.add(supTermPointZ);
+        TerminationPoint tpZ = new TerminationPointBuilder()
+            .setTpId(new TpId("XPDR1-NETWORK1"))
+            .setSupportingTerminationPoint(supTermPointListZ)
+            .addAugmentation(TerminationPoint1.class, otnTp1)
+            .addAugmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1.class,
+                new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1Builder()
+                .setTpType(OpenroadmTpType.XPONDERNETWORK)
+                .build())
+            .build();
+        List<TerminationPoint> tps = new ArrayList<>();
+        tps.add(tpA);
+        tps.add(tpZ);
+        return tps;
+    }
+
     private static List<Mapping> createDegreeMappings(List<Mapping> mappingList, int degNbStart, int degNbStop) {
         for (int i = degNbStart; i <= degNbStop; i++) {
             Mapping mapping = new MappingBuilder()
diff --git a/networkmodel/src/test/resources/portMapping.json b/networkmodel/src/test/resources/portMapping.json
new file mode 100644 (file)
index 0000000..c7fa75e
--- /dev/null
@@ -0,0 +1,303 @@
+{
+    "network": {
+        "nodes": [
+            {
+                "node-id": "XPDR-A1",
+                "mapping": [
+                    {
+                        "logical-connection-point": "XPDR1-NETWORK2",
+                        "port-qual": "xpdr-network",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "1",
+                        "connection-map-lcp": "XPDR1-CLIENT2",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-OCH"
+                        ],
+                        "lcp-hash-val": "8e128ba57560403cfd4ffafae38cd942",
+                        "supporting-circuit-pack-name": "1/0/2-PLUG-NET"
+                    },
+                    {
+                        "logical-connection-point": "XPDR1-NETWORK1",
+                        "port-qual": "xpdr-network",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "1",
+                        "connection-map-lcp": "XPDR1-CLIENT1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-OCH"
+                        ],
+                        "lcp-hash-val": "8e128ba57560403cfd4ffafae38cd941",
+                        "supporting-circuit-pack-name": "1/0/1-PLUG-NET"
+                    },
+                    {
+                        "logical-connection-point": "XPDR1-CLIENT1",
+                        "port-qual": "xpdr-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "C1",
+                        "connection-map-lcp": "XPDR1-NETWORK1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-100GE"
+                        ],
+                        "lcp-hash-val": "3ed8ed1336784ac7c2f66c22f2f03d8",
+                        "supporting-circuit-pack-name": "1/0/1-PLUG-CLIENT"
+                    },
+                    {
+                        "logical-connection-point": "XPDR1-CLIENT2",
+                        "port-qual": "xpdr-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "C1",
+                        "connection-map-lcp": "XPDR1-NETWORK2",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-100GE"
+                        ],
+                        "lcp-hash-val": "3ed8ed1336784ac7c2f66c22f2f03db",
+                        "supporting-circuit-pack-name": "1/0/2-PLUG-CLIENT"
+                    }
+                ],
+                "node-info": {
+                    "node-clli": "NodeA",
+                    "openroadm-version": "2.2.1",
+                    "node-model": "model2",
+                    "node-type": "xpdr",
+                    "node-vendor": "vendorA",
+                    "node-ip-address": "1.2.3.4"
+                }
+            },
+            {
+                "node-id": "SPDR-SA1",
+                "node-info": {
+                    "node-clli": "NodeSA",
+                    "openroadm-version": "2.2.1",
+                    "node-model": "universal-switchponder",
+                    "node-type": "xpdr",
+                    "node-vendor": "vendorA",
+                    "node-ip-address": "1.2.3.4"
+                },
+                "switching-pool-lcp": [
+                    {
+                        "switching-pool-number": 1,
+                        "switching-pool-type": "non-blocking",
+                        "non-blocking-list": [
+                            {
+                                "nbl-number": 11,
+                                "lcp-list": [
+                                    "XPDR1-CLIENT2",
+                                    "XPDR1-NETWORK1"
+                                ],
+                                "interconnect-bandwidth": 0,
+                                "interconnect-bandwidth-unit": 1000000000
+                            },
+                            {
+                                "nbl-number": 12,
+                                "lcp-list": [
+                                    "XPDR1-NETWORK1",
+                                    "XPDR1-CLIENT3"
+                                ],
+                                "interconnect-bandwidth": 0,
+                                "interconnect-bandwidth-unit": 1000000000
+                            },
+                            {
+                                "nbl-number": 13,
+                                "lcp-list": [
+                                    "XPDR1-CLIENT4",
+                                    "XPDR1-NETWORK1"
+                                ],
+                                "interconnect-bandwidth": 0,
+                                "interconnect-bandwidth-unit": 1000000000
+                            },
+                            {
+                                "nbl-number": 14,
+                                "lcp-list": [
+                                    "XPDR1-CLIENT1",
+                                    "XPDR1-NETWORK1"
+                                ],
+                                "interconnect-bandwidth": 0,
+                                "interconnect-bandwidth-unit": 1000000000
+                            }
+                        ]
+                    },
+                    {
+                        "switching-pool-number": 2,
+                        "switching-pool-type": "non-blocking",
+                        "non-blocking-list": [
+                            {
+                                "nbl-number": 2,
+                                "lcp-list": [
+                                    "XPDR2-CLIENT1",
+                                    "XPDR2-NETWORK3",
+                                    "XPDR2-NETWORK4",
+                                    "XPDR2-NETWORK1",
+                                    "XPDR2-NETWORK2",
+                                    "XPDR2-CLIENT4",
+                                    "XPDR2-CLIENT3",
+                                    "XPDR2-CLIENT2"
+                                ],
+                                "interconnect-bandwidth": 0,
+                                "interconnect-bandwidth-unit": 1000000000
+                            }
+                        ]
+                    }
+                ],
+                "mapping": [
+                    {
+                        "logical-connection-point": "XPDR1-NETWORK1",
+                        "port-qual": "xpdr-network",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP1-CFP0-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-OCH-OTU4-ODU4"
+                        ],
+                        "lcp-hash-val": "1021db8d2affe7386705c438c67ea21f",
+                        "xponder-type": "mpdr",
+                        "supporting-circuit-pack-name": "CP1-CFP0"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-CLIENT4",
+                        "port-qual": "switch-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP2-QSFP4-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-100GE-ODU4",
+                            "org-openroadm-port-types:if-100GE"
+                        ],
+                        "lcp-hash-val": "5ccce78a8e7367129679913aaa905e18",
+                        "supporting-circuit-pack-name": "CP2-QSFP4"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-CLIENT2",
+                        "port-qual": "switch-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP2-QSFP2-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-100GE-ODU4",
+                            "org-openroadm-port-types:if-100GE"
+                        ],
+                        "lcp-hash-val": "5ccce78a8e7367129679913aaa905e1e",
+                        "supporting-circuit-pack-name": "CP2-QSFP2"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-CLIENT3",
+                        "port-qual": "switch-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP2-QSFP3-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-100GE-ODU4",
+                            "org-openroadm-port-types:if-100GE"
+                        ],
+                        "lcp-hash-val": "5ccce78a8e7367129679913aaa905e1f",
+                        "supporting-circuit-pack-name": "CP2-QSFP3"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-CLIENT1",
+                        "port-qual": "switch-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP2-QSFP1-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-100GE-ODU4",
+                            "org-openroadm-port-types:if-100GE"
+                        ],
+                        "lcp-hash-val": "5ccce78a8e7367129679913aaa905e1d",
+                        "supporting-circuit-pack-name": "CP2-QSFP1"
+                    },
+                    {
+                        "logical-connection-point": "XPDR1-CLIENT3",
+                        "port-qual": "xpdr-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP1-SFP2-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-10GE-ODU2e",
+                            "org-openroadm-port-types:if-10GE-ODU2"
+                        ],
+                        "lcp-hash-val": "8b3efff522736722500b5e68fb6e696c",
+                        "supporting-circuit-pack-name": "CP1-SFP2"
+                    },
+                    {
+                        "logical-connection-point": "XPDR1-CLIENT4",
+                        "port-qual": "xpdr-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP1-SFP3-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-10GE-ODU2e",
+                            "org-openroadm-port-types:if-10GE-ODU2",
+                            "org-openroadm-port-types:if-10GE"
+                        ],
+                        "lcp-hash-val": "8b3efff522736722500b5e68fb6e696b",
+                        "supporting-circuit-pack-name": "CP1-SFP3"
+                    },
+                    {
+                        "logical-connection-point": "XPDR1-CLIENT1",
+                        "port-qual": "xpdr-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP1-SFP4-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-10GE-ODU2e",
+                            "org-openroadm-port-types:if-10GE-ODU2",
+                            "org-openroadm-port-types:if-10GE"
+                        ],
+                        "lcp-hash-val": "8b3efff522736722500b5e68fb6e696e",
+                        "supporting-circuit-pack-name": "CP1-SFP4"
+                    },
+                    {
+                        "logical-connection-point": "XPDR1-CLIENT2",
+                        "port-qual": "xpdr-client",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP1-SFP1-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-10GE-ODU2e",
+                            "org-openroadm-port-types:if-10GE-ODU2"
+                        ],
+                        "lcp-hash-val": "8b3efff522736722500b5e68fb6e696d",
+                        "supporting-circuit-pack-name": "CP1-SFP1"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-NETWORK2",
+                        "port-qual": "switch-network",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP6-CFP-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-OCH-OTU4-ODU4"
+                        ],
+                        "lcp-hash-val": "c58e095f5bffd3df5ee0842c78552191",
+                        "xponder-type": "switch",
+                        "supporting-circuit-pack-name": "CP6-CFP"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-NETWORK1",
+                        "port-qual": "switch-network",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP5-CFP-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-OCH-OTU4-ODU4"
+                        ],
+                        "lcp-hash-val": "c58e095f5bffd3df5ee0842c78552192",
+                        "xponder-type": "switch",
+                        "supporting-circuit-pack-name": "CP5-CFP"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-NETWORK4",
+                        "port-qual": "switch-network",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP8-CFP-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-OCH-OTU4-ODU4"
+                        ],
+                        "lcp-hash-val": "c58e095f5bffd3df5ee0842c78552197",
+                        "xponder-type": "switch",
+                        "supporting-circuit-pack-name": "CP8-CFP"
+                    },
+                    {
+                        "logical-connection-point": "XPDR2-NETWORK3",
+                        "port-qual": "switch-network",
+                        "port-direction": "bidirectional",
+                        "supporting-port": "CP7-CFP-P1",
+                        "supported-interface-capability": [
+                            "org-openroadm-port-types:if-OCH-OTU4-ODU4"
+                        ],
+                        "lcp-hash-val": "c58e095f5bffd3df5ee0842c78552190",
+                        "xponder-type": "switch",
+                        "supporting-circuit-pack-name": "CP7-CFP"
+                    }
+                ]
+            }
+        ]
+    }
+}