PCE update to support constraints 57/82557/26
authorshweta <sv111y@att.com>
Tue, 18 Jun 2019 17:12:49 +0000 (13:12 -0400)
committerguillaume.lambert <guillaume.lambert@orange.com>
Tue, 23 Jul 2019 12:59:34 +0000 (14:59 +0200)
- PCE Library update
- Constraints
- restructuring of code
- add oms-attributes to the topology config files for functional tests

JIRA: TRNSPRTPCE-95

Change-Id: I711b1cf9bae4fa8c4c2029486776ebc00ed411a2
Signed-off-by: shweta <sv111y@att.com>
24 files changed:
pce/pom.xml
pce/src/main/java/org/opendaylight/transportpce/pce/PceComplianceCheck.java
pce/src/main/java/org/opendaylight/transportpce/pce/PcePathDescription.java
pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java [changed mode: 0644->0755]
pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraints.java
pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ExtractTopoDataStoreImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/graph/InAlgoPathValidator.java [new file with mode: 0644]
pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraph.java
pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraphEdge.java [new file with mode: 0644]
pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java [new file with mode: 0644]
pce/src/main/java/org/opendaylight/transportpce/pce/impl/PceServiceRPCImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java [moved from pce/src/main/java/org/opendaylight/transportpce/pce/PceLink.java with 61% similarity]
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceNode.java [moved from pce/src/main/java/org/opendaylight/transportpce/pce/PceNode.java with 82% similarity]
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceResult.java [moved from pce/src/main/java/org/opendaylight/transportpce/pce/PceResult.java with 66% similarity]
pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java
pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml
tests/sample_configs/NW-for-test-5-4.xml
tests/sample_configs/NW-simple-topology.xml
tests/sample_configs/honeynode-topo.xml

index d2f0051624a774565db7dca60da0115ac53359b6..d5ace4a22d1b502f68b36670a8ac3c6b327adafd 100644 (file)
@@ -61,9 +61,9 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>net.sf.jung2</artifactId>
-      <version>2.0.1</version>
+      <groupId>org.jgrapht</groupId>
+      <artifactId>jgrapht-core</artifactId>
+      <version>1.1.1-SNAPSHOT</version>
     </dependency>
 
     <!-- Testing Dependencies -->
@@ -96,4 +96,12 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
     </dependency>
   </dependencies>
 
+  <repositories>
+    <repository>
+      <id>browserid-snapshots</id>
+      <name>browserid-snapshots</name>
+      <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
+    </repository>
+  </repositories>
+
 </project>
index b4d13b5d764d3eb374040e04e2c22ca1985d5e7b..b7c8450273fdf55005c380d0de927aaf479c750b 100644 (file)
@@ -22,21 +22,23 @@ public final class PceComplianceCheck {
     }
 
     /*
-     * Check if a String is not
-     * null and not equal to ''.
+     * Check if a String is not null and not equal to ''.
      *
      * @param value String value
+     *
      * @return  true  if String ok
      *          false if not
      */
     public static boolean checkString(String value) {
-        return ((value != null) && (value.compareTo("") != 0));
+        return (value != null) && (value.compareTo("") != 0);
     }
 
     public static PceComplianceCheckResult check(PathComputationRequestInput input) {
         String message = "";
         Boolean result = true;
         if (input != null) {
+            LOG.info("New request {} for new service {}",
+                    input.getServiceHandlerHeader().getRequestId(), input.getServiceName());
             if (!checkString(input.getServiceName())) {
                 result = false;
                 message = "Service Name is not set";
@@ -55,4 +57,3 @@ public final class PceComplianceCheck {
     }
 
 }
-
index 31486dbad38eceac666570a5396d4dbf34f1e98e..287e74ecc3fa04f3d1aa1738e049607e671ba370 100644 (file)
@@ -12,6 +12,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import org.opendaylight.transportpce.common.ResponseCodes;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceLink;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirectionBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ZToADirectionBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.atoz.direction.AToZ;
@@ -32,13 +34,13 @@ import org.slf4j.LoggerFactory;
 
 public class PcePathDescription {
     /* Logging. */
-    private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
+    private static final Logger LOG = LoggerFactory.getLogger(PcePathDescription.class);
 
     private List<PceLink> pathAtoZ = null;
     private PceResult rc;
 
     public PceResult getReturnStructure() {
-        return this.rc;
+        return rc;
     }
 
     private Map<LinkId, PceLink> allPceLinks = null;
@@ -53,34 +55,38 @@ public class PcePathDescription {
     }
 
     public PceResult buildDescriptions() {
-        LOG.info("In buildDescriptions: AtoZ {}", this.pathAtoZ.toString());
+        LOG.info("In buildDescriptions: AtoZ {}", pathAtoZ.toString());
         List<AToZ> atozList = new ArrayList<AToZ>();
-        if (this.pathAtoZ == null) {
-            this.rc.setRC(ResponseCodes.RESPONSE_FAILED);
+        if (pathAtoZ == null) {
+            rc.setRC(ResponseCodes.RESPONSE_FAILED);
             LOG.error("In buildDescriptions: there is empty AtoZ path");
-            return this.rc;
+            return rc;
         }
 
-        buildAtoZ(atozList, this.pathAtoZ);
+        buildAtoZ(atozList, pathAtoZ);
 
-        this.rc.setAtoZDirection(new AToZDirectionBuilder().setRate(this.rc.getRate())
-                .setAToZWavelengthNumber(this.rc.getResultWavelength()).setAToZ(atozList).build());
+        rc.setAtoZDirection(new AToZDirectionBuilder()
+            .setRate(rc.getRate())
+            .setAToZWavelengthNumber(rc.getResultWavelength())
+            .setAToZ(atozList).build());
 
-        this.pathZtoA = ImmutableList.copyOf(this.pathAtoZ).reverse();
-        LOG.info("In buildDescriptions: ZtoA {}", this.pathZtoA.toString());
+        pathZtoA = ImmutableList.copyOf(pathAtoZ).reverse();
+        LOG.info("In buildDescriptions: ZtoA {}", pathZtoA.toString());
 
         List<ZToA> ztoaList = new ArrayList<ZToA>();
-        if (this.pathZtoA == null) {
-            this.rc.setRC(ResponseCodes.RESPONSE_FAILED);
+        if (pathZtoA == null) {
+            rc.setRC(ResponseCodes.RESPONSE_FAILED);
             LOG.error("In buildDescriptions: there is empty ZtoA path");
-            return this.rc;
+            return rc;
         }
-        buildZtoA(ztoaList, this.pathZtoA);
+        buildZtoA(ztoaList, pathZtoA);
 
-        this.rc.setZtoADirection(new ZToADirectionBuilder().setRate(this.rc.getRate())
-                .setZToAWavelengthNumber(this.rc.getResultWavelength()).setZToA(ztoaList).build());
+        rc.setZtoADirection(new ZToADirectionBuilder()
+            .setRate(rc.getRate())
+            .setZToAWavelengthNumber(rc.getResultWavelength())
+            .setZToA(ztoaList).build());
 
-        return this.rc;
+        return rc;
     }
 
     private void buildAtoZ(List<AToZ> etoeList, List<PceLink> path) {
@@ -100,13 +106,9 @@ public class PcePathDescription {
         Resource clientResource = new ResourceBuilder().setResource(stp).build();
         AToZ firstResource = new AToZBuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
         etoeList.add(firstResource);
-
         index++;
-
         for (PceLink pcelink : path) {
-
             String srcName = pcelink.getSourceId().getValue();
-
             // Nodes
             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.pce
                 .resource.resource.resource.Node sourceNode = new NodeBuilder()
@@ -152,8 +154,8 @@ public class PcePathDescription {
             // target TP
             tpName = pcelink.getDestTP().toString();
             TerminationPoint dtp = new TerminationPointBuilder()
-                    .setTpNodeId(destName).setTpId(tpName)
-                    .build();
+                .setTpNodeId(destName).setTpId(tpName)
+                .build();
 
             // Resource
             AToZKey destTPKey = new AToZKey(index.toString());
old mode 100644 (file)
new mode 100755 (executable)
index f05e230..96161a2
@@ -10,12 +10,16 @@ package org.opendaylight.transportpce.pce;
 
 import java.util.List;
 
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.transportpce.pce.PceResult.LocalCause;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.transportpce.pce.constraints.PceConstraints;
+import org.opendaylight.transportpce.pce.constraints.PceConstraintsCalc;
 import org.opendaylight.transportpce.pce.gnpy.ConnectToGnpyServer;
 import org.opendaylight.transportpce.pce.gnpy.ExtractTopoDataStoreImpl;
 import org.opendaylight.transportpce.pce.gnpy.GnpyResult;
 import org.opendaylight.transportpce.pce.gnpy.ServiceDataStoreOperationsImpl;
+import org.opendaylight.transportpce.pce.graph.PceGraph;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceCalculation;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApiBuilder;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.ServiceFileBuilder;
@@ -54,7 +58,7 @@ public class PceSendingPceRPCs {
      */
     private PathDescriptionBuilder pathDescription;
     private PathComputationRequestInput input;
-    private DataBroker dataBroker;
+    private NetworkTransactionService networkTransaction;
     private PceConstraints pceHardConstraints = new PceConstraints();
     private PceConstraints pceSoftConstraints = new PceConstraints();
     private Long gnpyRequestId = new Long(0);
@@ -64,17 +68,18 @@ public class PceSendingPceRPCs {
     public PceSendingPceRPCs() {
         setPathDescription(null);
         this.input = null;
-        this.dataBroker = null;
+        this.networkTransaction = null;
         this.gnpyAtoZ = null;
         this.gnpyZtoA = null;
     }
 
-    public PceSendingPceRPCs(PathComputationRequestInput input, DataBroker dataBroker) {
+    public PceSendingPceRPCs(PathComputationRequestInput input,
+            NetworkTransactionService networkTransaction) {
         setPathDescription(null);
 
         // TODO compliance check to check that input is not empty
         this.input = input;
-        this.dataBroker = dataBroker;
+        this.networkTransaction = networkTransaction;
     }
 
     public void cancelResourceReserve() {
@@ -89,21 +94,65 @@ public class PceSendingPceRPCs {
     }
 
     public void pathComputation() throws Exception {
-        // Comput the path according to the constraints of PCE
-        rc = pathComputationPCE();
+        LOG.info("PathComputation ...");
+
+        PceConstraintsCalc constraints = new PceConstraintsCalc(input,networkTransaction);
+        pceHardConstraints = constraints.getPceHardConstraints();
+        pceSoftConstraints = constraints.getPceSoftConstraints();
+        LOG.info("nwAnalizer ...");
+        PceCalculation nwAnalizer =
+            new PceCalculation(input,networkTransaction, pceHardConstraints, pceSoftConstraints, rc);
+        nwAnalizer.calcPath();
+        rc = nwAnalizer.getReturnStructure();
+        if (!rc.getStatus()) {
+            LOG.error("In pathComputation nwAnalizer: result = {}", rc.toString());
+            return;
+        }
+
+        LOG.info("PceGraph ...");
+        PceGraph graph = new PceGraph(nwAnalizer.getaendPceNode(),
+                nwAnalizer.getzendPceNode(), nwAnalizer.getAllPceNodes(),
+                pceHardConstraints, pceSoftConstraints, rc);
+        graph.calcPath();
+        rc = graph.getReturnStructure();
+        if (!rc.getStatus()) {
+            LOG.warn("In pathComputation : Graph return without Path ");
+            // TODO fix. This is quick workaround for algorithm problem
+            if ((rc.getLocalCause() == PceResult.LocalCause.TOO_HIGH_LATENCY)
+                    && (pceHardConstraints.getPceMetrics() == PceMetric.HopCount)
+                    && (pceHardConstraints.getMaxLatency() != -1)) {
+                pceHardConstraints.setPceMetrics(PceMetric.PropagationDelay);
+                graph = patchRerunGraph(graph);
+            }
+
+            if (!rc.getStatus()) {
+                LOG.error("In pathComputation graph.calcPath: result = {}", rc.toString());
+                return;
+            }
+        }
+
+        LOG.info("PcePathDescription ...");
+        PcePathDescription description = new PcePathDescription(graph.getPathAtoZ(), nwAnalizer.getAllPceLinks(), rc);
+        description.buildDescriptions();
+        rc = description.getReturnStructure();
+        if (!rc.getStatus()) {
+            LOG.error("In pathComputation description: result = {}", rc.toString());
+            return;
+        }
 
         LOG.info("setPathDescription ...");
         AToZDirection atoz = rc.getAtoZDirection();
         ZToADirection ztoa = rc.getZtoADirection();
         ConnectToGnpyServer connectToGnpy = new ConnectToGnpyServer();
-        if ((atoz == null) || (atoz.getAToZ() == null)) {
+        if (atoz == null || atoz.getAToZ() == null) {
             rc.setRC("400");
-            LOG.warn("In PCE pathComputation: empty atoz path after description: result = {}", rc.toString());
+            LOG.error("In pathComputation empty atoz path after description: result = {}", rc.toString());
             return;
         } else {
             // Send the computed path A-to-Z to GNPY tool
             if (connectToGnpy.isGnpyURLExist()) {
-                ExtractTopoDataStoreImpl xtrTopo = new ExtractTopoDataStoreImpl(dataBroker, input, atoz, gnpyRequestId);
+                ExtractTopoDataStoreImpl xtrTopo = new ExtractTopoDataStoreImpl(networkTransaction, input, atoz,
+                        gnpyRequestId);
                 gnpyRequestId++;
                 List<Elements> elementsList1 = xtrTopo.getElements();
                 List<Connections> connectionsList1 = xtrTopo.getConnections();
@@ -123,14 +172,15 @@ public class PceSendingPceRPCs {
             }
         }
 
-        if ((ztoa == null) || (ztoa.getZToA() == null)) {
+        if (ztoa == null || ztoa.getZToA() == null) {
             rc.setRC("400");
             LOG.error("In pathComputation empty ztoa path after description: result = {}", rc.toString());
             return;
         } else {
             // Send the computed path Z-to-A to GNPY tool
             if (connectToGnpy.isGnpyURLExist()) {
-                ExtractTopoDataStoreImpl xtrTopo = new ExtractTopoDataStoreImpl(dataBroker, input, ztoa, gnpyRequestId);
+                ExtractTopoDataStoreImpl xtrTopo = new ExtractTopoDataStoreImpl(networkTransaction, input, ztoa,
+                        gnpyRequestId);
                 gnpyRequestId++;
                 List<Elements> elementsList2 = xtrTopo.getElements();
                 List<Connections> connectionsList2 = xtrTopo.getConnections();
@@ -149,59 +199,11 @@ public class PceSendingPceRPCs {
                 }
             }
         }
-        // Set the description of the path
+
         setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
         LOG.info("In pathComputation Graph is Found");
     }
 
-    public PceResult pathComputationPCE() {
-        LOG.info("PathComputation ...");
-
-        PceConstraintsCalc constraints = new PceConstraintsCalc(input, dataBroker);
-        pceHardConstraints = constraints.getPceHardConstraints();
-        pceSoftConstraints = constraints.getPceSoftConstraints();
-
-        LOG.info("nwAnalizer ...");
-        PceCalculation nwAnalizer = new PceCalculation(input, dataBroker, pceHardConstraints, pceSoftConstraints, rc);
-        nwAnalizer.calcPath();
-        rc = nwAnalizer.getReturnStructure();
-        if (!rc.getStatus()) {
-            LOG.error("In pathComputation nwAnalizer: result = {}", rc.toString());
-            return null;
-        }
-
-        LOG.info("PceGraph ...");
-        LOG.warn("PathComputation: aPceNode '{}' - zPceNode '{}'", nwAnalizer.getaPceNode(), nwAnalizer.getzPceNode());
-        PceGraph graph = new PceGraph(nwAnalizer.getaPceNode(), nwAnalizer.getzPceNode(), nwAnalizer.getAllPceNodes(),
-                pceHardConstraints, pceSoftConstraints, rc);
-        graph.calcPath();
-        rc = graph.getReturnStructure();
-        if (!rc.getStatus()) {
-            LOG.warn("In pathComputation : Graph return without Path ");
-            // TODO fix. This is quick workaround for algorithm problem
-            if ((rc.getLocalCause() == LocalCause.TOO_HIGH_LATENCY)
-                    && (pceHardConstraints.getPceMetrics() == PceMetric.HopCount)
-                    && (pceHardConstraints.getMaxLatency() != -1)) {
-                pceHardConstraints.setPceMetrics(PceMetric.PropagationDelay);
-                graph = patchRerunGraph(graph);
-            }
-            if (!rc.getStatus()) {
-                LOG.error("In pathComputation graph.calcPath: result = {}", rc.toString());
-                return null;
-            }
-        }
-
-        LOG.info("PcePathDescription ...");
-        PcePathDescription description = new PcePathDescription(graph.getPathAtoZ(), nwAnalizer.getAllPceLinks(), rc);
-        description.buildDescriptions();
-        rc = description.getReturnStructure();
-        if (!rc.getStatus()) {
-            LOG.error("In pathComputation description: result = {}", rc.toString());
-            return null;
-        }
-        return rc;
-    }
-
     private String getGnpyResponse(List<Elements> elementsList, List<Connections> connectionsList,
             List<PathRequest> pathRequestList, List<Synchronization> synchronizationList) throws Exception {
         GnpyApi gnpyApi = new GnpyApiBuilder()
@@ -210,7 +212,7 @@ public class PceSendingPceRPCs {
                 .setServiceFile(new ServiceFileBuilder().setPathRequest(pathRequestList).build()).build();
         InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
         String gnpyJson;
-        ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(dataBroker);
+        ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(networkTransaction);
         gnpyJson = sd.createJsonStringFromDataObject(idGnpyApi, gnpyApi);
         LOG.debug("GNPy  Id: {} / json created : {}", idGnpyApi, gnpyJson);
         ConnectToGnpyServer connect = new ConnectToGnpyServer();
@@ -225,7 +227,6 @@ public class PceSendingPceRPCs {
         graph.setConstrains(pceHardConstraints, pceSoftConstraints);
         graph.calcPath();
         return graph;
-
     }
 
     public PathDescriptionBuilder getPathDescription() {
index 5e878e02f8e1e4b6035d2c6958870ff82c6d456a..b5e8c7978ce4167d786089120296e5b353f41249 100644 (file)
@@ -5,10 +5,12 @@
  * 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.pce;
+package org.opendaylight.transportpce.pce.constraints;
 
 import java.util.ArrayList;
 import java.util.List;
+
+import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -16,19 +18,40 @@ import org.slf4j.LoggerFactory;
 // internal type after parsing
 public class PceConstraints {
     /* Logging. */
-    private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
+    private static final Logger LOG = LoggerFactory.getLogger(PceConstraints.class);
 
     // TODO. for now metrics are set into hard structure
     private RoutingConstraintsSp.PceMetric pceMetrics = RoutingConstraintsSp.PceMetric.HopCount;
     private Long maxLatency = (long) -1;
 
+    /////////////// EXCLUDE ///////////////////
+    // Nodes/CLLI/SRLG lists might consist of two types of elements : (1)from diversity constraints (2)from exclude list
+    // e.g.: nodesToExclude - topo-level nodes IDs - comes from diversity constraints
+    //     : supNodesToExclude - supporting nodes IDs - comes from exclude list
+    // "mapConstraints" class converts diversity elements into correct names
     private List<String> nodesToExclude = new ArrayList<String>();
-    private List<String> srlgToExclude = new ArrayList<String>();
+    private List<String> supNodesToExclude = new ArrayList<String>();
+
+    private List<Long> srlgToExclude = new ArrayList<Long>();
+    private List<String> srlgLinksToExclude = new ArrayList<String>();
+
+    private List<String> clliToExclude = new ArrayList<String>();
+    private List<String> clliNodesToExclude = new ArrayList<String>();
     private List<String> nodesToInclude = new ArrayList<String>();
     private List<PceNode> pceNodesToInclude = new ArrayList<PceNode>();
+
     public static final Long CONST_OSNR = 1L;
     private double maxOSNR = (CONST_OSNR / (Math.pow(10, (24 / 10.0))));
 
+    /**.
+     * /////////////// INCLUDE CONSTRAINTS.///////////////////
+     */
+    private List<ResourcePair> listToInclude = new ArrayList<ResourcePair>();
+    private List<String> srlgNames = new ArrayList<String>();
+
+    public enum ResourceType {
+        NONE, NODE, SRLG, CLLI;
+    }
 
     public RoutingConstraintsSp.PceMetric getPceMetrics() {
         return pceMetrics;
@@ -50,27 +73,70 @@ public class PceConstraints {
         this.maxLatency = maxLatency;
     }
 
-    // Exclude nodes / SRLD /
-    public List<String> getExcludeNodes() {
-        LOG.debug("in Pceconstraints getExcludeNodes size = {}", nodesToExclude.size());
-        return nodesToExclude;
+    // Exclude nodes / SRLD / CLLI
+
+    public List<String> getExcludeSupNodes() {
+        LOG.debug("in Pceconstraints getExcludeSupNodes size = {}", supNodesToExclude.size());
+        return supNodesToExclude;
     }
 
-    public void setExcludeNodes(List<String> nodes) {
-        LOG.debug("in Pceconstraints setExcludeNodes size = {}", nodes.size());
-        nodesToExclude.addAll(nodes);
+    public void setExcludeSupNodes(List<String> supNodes) {
+        LOG.debug("in Pceconstraints setExcludeSupNodes size = {}", supNodes.size());
+        supNodesToExclude.addAll(supNodes);
     }
 
-    public List<String> getExcludeSRLG() {
+    public List<Long> getExcludeSRLG() {
         LOG.debug("in Pceconstraints getExcludeSRLG size = {}", srlgToExclude.size());
         return srlgToExclude;
     }
 
-    public void setExcludeSRLG(List<String> srlg) {
-        LOG.debug("in Pceconstraints setExcludeSRLG size = {}", srlg.size());
+    public void setExcludeSRLG(List<Long> srlg) {
+        LOG.info("in Pceconstraints setExcludeSRLG size = {}", srlg.size());
         srlgToExclude.addAll(srlg);
     }
 
+    public List<String> getExcludeCLLI() {
+        LOG.debug("in Pceconstraints getExcludeCLLI size = {}", clliToExclude.size());
+        return clliToExclude;
+    }
+
+    public void setExcludeCLLI(List<String> clli) {
+        LOG.debug("in Pceconstraints setExcludeCLLI size = {}", clli.size());
+        clliToExclude.addAll(clli);
+    }
+
+    // CLLI nodes are defined as result of 'diversity 'node'' constraints
+    // clliNodesToExclude are saved as nodes, during NW analysis the relevant
+    // CLLI IDs are added to clliToExclude
+    public List<String> getExcludeClliNodes() {
+        LOG.info("in Pceconstraints getExcludeClliNodes size = {}", clliNodesToExclude.size());
+        return clliNodesToExclude;
+    }
+
+    public void setExcludeClliNodes(List<String> clli) {
+        LOG.debug("in Pceconstraints setExcludeCLLI size = {}", clli.size());
+        clliNodesToExclude.addAll(clli);
+    }
+
+    public List<String> getExcludeSrlgLinks() {
+        LOG.info("in Pceconstraints getExcludeSrlgNodes size = {}", srlgLinksToExclude.size());
+        return srlgLinksToExclude;
+    }
+
+    public void setExcludeSrlgLinks(List<String> srlg) {
+        LOG.debug("in Pceconstraints setExcludeSRLG size = {}", srlg.size());
+        srlgLinksToExclude.addAll(srlg);
+    }
+
+    public List<String> getExcludeNodes() {
+        LOG.info("in Pceconstraints getExcludeNodes size = {}", nodesToExclude.size());
+        return nodesToExclude;
+    }
+
+    public void setExcludeNodes(List<String> nodes) {
+        LOG.debug("in Pceconstraints setExcludeNodes size = {}", nodes.size());
+        nodesToExclude.addAll(nodes);
+    }
 
     // Include nodes
     public List<String> getIncludeNodes() {
@@ -98,5 +164,34 @@ public class PceConstraints {
         return maxOSNR;
     }
 
+    public class ResourcePair {
+        public ResourcePair(ResourceType type, String name) {
+            super();
+            this.type = type;
+            this.name = name;
+        }
+
+        public ResourceType type = ResourceType.NODE;
+
+        public String name = "";
+    }
+
+    public List<ResourcePair> getListToInclude() {
+        return listToInclude;
+    }
 
+    public void setListToInclude(ResourcePair elementToInclude) {
+        this.listToInclude.add(elementToInclude);
+        switch (elementToInclude.type) {
+            case SRLG:
+                srlgNames.add(elementToInclude.name);
+                break;
+            default:
+                break;
+        }
+    }
+
+    public List<String> getSRLGnames() {
+        return srlgNames;
+    }
 }
index ae6b8d5611bd59edf9ebe0bd46741260dd915750..1b8372ef683b08b457205ae25cd2d4ff47d33e6f 100644 (file)
@@ -1,26 +1,28 @@
 /*
- * Copyright Â© 2017 AT&T, Inc. and others.  All rights reserved.
+ * Copyright Â© 2016 AT&T 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.pce;
+package org.opendaylight.transportpce.pce.constraints;
 
 import com.google.common.base.Optional;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.transportpce.common.Timeouts;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.PathDescription;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.pce.resource.resource.resource.Link;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.pce.resource.resource.resource.Node;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp.PceMetric;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.CoRoutingOrGeneral;
@@ -28,36 +30,40 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.General;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Diversity;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Exclude;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Include;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Latency;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.include_.OrderedHops;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.diversity.existing.service.contraints.sp.ExistingServiceApplicability;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.ordered.constraints.sp.hop.type.HopType;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.SoftConstraints;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class PceConstraintsCalc {
     /* Logging. */
-    private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
+    private static final Logger LOG = LoggerFactory.getLogger(PceConstraintsCalc.class);
 
     private PceConstraints pceHardConstraints = new PceConstraints();
     private PceConstraints pceSoftConstraints = new PceConstraints();
     private PceMetric pceMetrics = PceMetric.HopCount;
-    private DataBroker dataBroker;
+    private NetworkTransactionService networkTransactionService;
 
-
-    public PceConstraintsCalc(PathComputationRequestInput input, DataBroker dataBroker) {
+    public PceConstraintsCalc(PathComputationRequestInput input, NetworkTransactionService networkTransactionService) {
         LOG.debug("In PceconstraintsCalc start");
 
-        this.pceMetrics = input.getPceMetric();
+        pceMetrics = input.getPceMetric();
 
-        this.dataBroker = dataBroker;
+        this.networkTransactionService = networkTransactionService;
 
         // TODO. for now metrics are set into hard structure
-        LOG.info("In PceConstraintsCalc: read PceMetric {}", this.pceMetrics.toString());
-        this.pceHardConstraints.setPceMetrics(this.pceMetrics);
+        LOG.info("In PceConstraintsCalc: read PceMetric {}", pceMetrics.toString());
+        pceHardConstraints.setPceMetrics(pceMetrics);
 
         calcHardconstraints(input);
         calcSoftconstraints(input);
@@ -71,7 +77,7 @@ public class PceConstraintsCalc {
         }
 
         CoRoutingOrGeneral coRoutingOrGeneral = servicePathHardConstraints.getCoRoutingOrGeneral();
-        readconstraints(coRoutingOrGeneral, this.pceHardConstraints);
+        readconstraints(coRoutingOrGeneral, pceHardConstraints);
 
     }
 
@@ -83,7 +89,7 @@ public class PceConstraintsCalc {
         }
 
         CoRoutingOrGeneral coRoutingOrGeneral = servicePathSoftConstraints.getCoRoutingOrGeneral();
-        readconstraints(coRoutingOrGeneral, this.pceSoftConstraints);
+        readconstraints(coRoutingOrGeneral, pceSoftConstraints);
 
     }
 
@@ -119,7 +125,7 @@ public class PceConstraintsCalc {
     private void readGeneralContrains(General tmpGeneral, PceConstraints constraints) {
         LOG.debug("In readGeneralContrains start");
 
-        if (tmpGeneral  ==  null) {
+        if (tmpGeneral == null) {
             LOG.info("In readGeneralContrains: no General constraints.");
             return;
         }
@@ -135,69 +141,189 @@ public class PceConstraintsCalc {
         if (exclude != null) {
             elementsToExclude = exclude.getNodeId();
             if (elementsToExclude != null) {
-                constraints.setExcludeNodes(elementsToExclude);
+                constraints.setExcludeSupNodes(elementsToExclude);
             }
+
             elementsToExclude = exclude.getSRLG();
             if (elementsToExclude != null) {
-                constraints.setExcludeSRLG(elementsToExclude);
+                List<Long> srlgToExclude = new ArrayList<Long>();
+                for (String str : elementsToExclude) {
+                    srlgToExclude.add(Long.parseLong(str));
+                }
+                constraints.setExcludeSRLG(srlgToExclude);
+            }
+
+            elementsToExclude = exclude.getClli();
+            if (elementsToExclude != null) {
+                constraints.setExcludeCLLI(elementsToExclude);
             }
         }
 
+        Include include = tmpGeneral.getInclude();
+        if (include != null) {
+            List<OrderedHops> listHops = include.getOrderedHops();
+            if (listHops != null) {
+                readIncludeNodes(listHops, constraints);
+            }
+            LOG.debug("in readGeneralContrains INCLUDE {} ", include.toString());
+        }
+
         Diversity diversity = tmpGeneral.getDiversity();
-        if ((diversity != null) && (diversity.getExistingServiceApplicability().isNode())) {
-            LOG.info("in readGeneralContrains {}", diversity.toString());
-            readDiversityNodes(diversity.getExistingService(), constraints);
+        PceConstraints.ResourceType rt = PceConstraints.ResourceType.NONE;
+        if (diversity != null) {
+            ExistingServiceApplicability temp = diversity.getExistingServiceApplicability();
+            if (temp == null) {
+                return;
+            }
+            if (temp.isNode()) {
+                rt = PceConstraints.ResourceType.NODE;
+            }
+            if (temp.isSrlg()) {
+                rt = PceConstraints.ResourceType.SRLG;
+            }
+            if (temp.isClli()) {
+                rt = PceConstraints.ResourceType.CLLI;
+            }
+            LOG.info("in readGeneralContrains {} list is :{}", rt, diversity.toString());
+            readDiversity(diversity.getExistingService(), constraints, rt);
         }
 
     }
 
-    private void readDiversityNodes(List<String> srvList, PceConstraints constraints) {
+    private void readIncludeNodes(List<OrderedHops> listHops, PceConstraints constraints) {
+        for (int i = 0; i < listHops.size(); i++) {
+            HopType hoptype = listHops.get(i).getHopType().getHopType();
+
+            String hopt = hoptype.getImplementedInterface().getSimpleName();
+            LOG.info("in readIncludeNodes next hop to include {}", hopt);
+            switch (hopt) {
+                case "Node":
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints
+                            .rev171017.ordered.constraints.sp.hop.type.hop.type.Node
+                            node = (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
+                            .constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.Node) hoptype;
+                    constraints.setListToInclude(constraints.new ResourcePair(PceConstraints.ResourceType.NODE,
+                            node.getNodeId()));
+                    break;
+                case "SRLG":
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints
+                            .rev171017.ordered.constraints.sp.hop.type.hop.type.SRLG
+                            srlg = (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
+                            .constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.SRLG) hoptype;
+                    constraints.setListToInclude(constraints.new ResourcePair(PceConstraints.ResourceType.SRLG,
+                            srlg.getSRLG()));
+                    break;
+                case "Clli":
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints
+                            .rev171017.ordered.constraints.sp.hop.type.hop.type.Clli
+                            clli = (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
+                            .constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.Clli) hoptype;
+                    constraints.setListToInclude(constraints.new ResourcePair(PceConstraints.ResourceType.CLLI,
+                            clli.getClli()));
+                    break;
+                default:
+                    LOG.error("in readIncludeNodes unsupported include type {}", hopt);
+            }
+        }
+    }
+
+    private void readDiversity(List<String> srvList, PceConstraints constraints, PceConstraints.ResourceType rt) {
 
         List<String> elementsToExclude = new ArrayList<String>();
-        LOG.info("in readDiversityNodes {}", srvList.toString());
+        LOG.info("in readDiversity {}", srvList.toString());
 
         for (String srv : srvList) {
             Optional<PathDescription> service = getPathDescriptionFromDatastore(srv);
             if (service.isPresent()) {
-                elementsToExclude.addAll(getAToZNodeList(service.get()));
-                LOG.info("readDiversityNodes : {}", elementsToExclude);
+                LOG.info("in readDiversity service list {}", service.toString());
+                switch (rt) {
+                    case NODE:
+                        elementsToExclude
+                                .addAll(getAToZNodeList(service.get()));
+                        LOG.info("readDiversity NODE : {}", elementsToExclude);
+                        if (elementsToExclude != null) {
+                            constraints.setExcludeNodes(elementsToExclude);
+                        }
+                        break;
+                    case SRLG:
+                        elementsToExclude
+                                .addAll(getSRLGList(service.get()));
+                        LOG.info("readDiversity SRLG : {}", elementsToExclude);
+                        if (elementsToExclude != null) {
+                            constraints.setExcludeSrlgLinks(elementsToExclude);
+                        }
+                        break;
+                    case CLLI:
+                        /// Retrieve nodes into dedicated CLLI list
+                        /// during node validation check their CLLI and build CLLI exclude list
+                        elementsToExclude
+                                .addAll(getAToZNodeList(service.get()));
+                        LOG.info("readDiversity CLLI : {}", elementsToExclude);
+                        if (elementsToExclude != null) {
+                            constraints.setExcludeClliNodes(elementsToExclude);
+                        }
+                        break;
+                    default:
+                        LOG.info("in readDiversity unsupported divercity type", rt);
+                }
 
             } else {
-                LOG.info("in readDiversityNodes srv={} is not present", srv);
+                LOG.info("in readDiversity srv={} is not present", srv);
             }
         }
 
-        if (elementsToExclude != null) {
-            constraints.setExcludeNodes(elementsToExclude);
-        }
     }
 
     private List<String> getAToZNodeList(PathDescription pathDescription) {
-        List<AToZ> atozList = pathDescription.getAToZDirection().getAToZ();
-        return atozList.stream().filter(aToZ -> {
-            if ((aToZ.getResource() == null) || (aToZ.getResource().getResource() == null)) {
+        List<AToZ> aendToZList = pathDescription.getAToZDirection().getAToZ();
+        return aendToZList.stream().filter(aToZ -> {
+            if (aToZ.getResource() == null || aToZ.getResource().getResource() == null) {
                 LOG.warn("Diversity constraint: Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
                 return false;
             }
             return aToZ.getResource().getResource() instanceof Node;
-        }).map(aToZ -> {
+        }).filter(aToZ -> {
             Node node = (Node) aToZ.getResource().getResource();
             if (node.getNodeId() == null) {
                 LOG.warn("Node in AToZ node {} contains null! Skipping this node!", aToZ.getId());
-                return null;
+                return false;
             }
+            return true;
+        }).map(aToZ -> {
+            Node node = ((Node) aToZ.getResource().getResource());
             return node.getNodeId().toString();
         }).collect(Collectors.toList());
     }
 
+    private List<String> getSRLGList(PathDescription pathDescription) {
+        List<AToZ> aendToZList = pathDescription.getAToZDirection().getAToZ();
+        return aendToZList.stream().filter(aToZ -> {
+            if (aToZ.getResource() == null
+                    || aToZ.getResource().getResource() == null) {
+                LOG.warn("Diversity constraint: Resource of AToZ {} is null! Skipping this resource!", aToZ.getId());
+                return false;
+            }
+            return aToZ.getResource().getResource() instanceof Link;
+        }).filter(aToZ -> {
+            Link link = (Link) aToZ.getResource().getResource();
+            if (link.getLinkId() == null) {
+                LOG.warn("Link in AToZ link {} contains null! Skipping this link!", aToZ.getId());
+                return false;
+            }
+            return true;
+        }).map(aToZ -> {
+            return ((Link) aToZ.getResource().getResource()).getLinkId();
+        }).collect(Collectors.toList());
+    }
+
     private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
         Optional<PathDescription> result = Optional.absent();
         InstanceIdentifier<ServicePaths> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
-        ReadOnlyTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
         try {
             LOG.info("PCE diversity constraints: Getting path description for service {}", serviceName);
-            ServicePaths servicePaths = pathDescReadTx.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
+            ServicePaths servicePaths =
+                networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).get();
             if (servicePaths != null) {
                 PathDescription path = servicePaths.getPathDescription();
@@ -205,6 +331,8 @@ public class PceConstraintsCalc {
                     result = Optional.of(path);
                 }
             }
+//            return pathDescReadTx.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
+//                    .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
         } catch (InterruptedException | ExecutionException | TimeoutException e) {
             LOG.warn(
                 "PCE diversity constraints: Exception while getting path description from datastore {} for service {}!",
@@ -217,7 +345,7 @@ public class PceConstraintsCalc {
     private void readCoRoutingContrains(CoRouting tmpcoRouting, PceConstraints constraints) {
         LOG.info("In readCoRoutingContrains start");
 
-        if (tmpcoRouting  ==  null) {
+        if (tmpcoRouting == null) {
             LOG.info("In readCoRoutingContrains: no General constraints.");
             return;
         }
@@ -225,16 +353,15 @@ public class PceConstraintsCalc {
     }
 
     public PceConstraints getPceHardConstraints() {
-        return this.pceHardConstraints;
+        return pceHardConstraints;
     }
 
     public PceConstraints getPceSoftConstraints() {
-        return this.pceSoftConstraints;
+        return pceSoftConstraints;
     }
 
     public PceMetric getPceMetrics() {
-        return this.pceMetrics;
+        return pceMetrics;
     }
 
-
 }
index 5c0d4031bff25cbe78d16132e97c9f306023b634..09c8511b217753b9dac80b9672827e9d8a3c48ea 100644 (file)
@@ -17,10 +17,9 @@ import java.util.concurrent.ExecutionException;
 import java.util.stream.IntStream;
 
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.transportpce.common.NetworkUtils;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.Coordinate;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.Km;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.edfa.params.Operational;
@@ -103,7 +102,7 @@ import org.slf4j.LoggerFactory;
 
 public class ExtractTopoDataStoreImpl {
     private static final Logger LOG = LoggerFactory.getLogger(ExtractTopoDataStoreImpl.class);
-    private final DataBroker dataBroker;
+    private final NetworkTransactionService networkTransactionService;
     private List<Elements> elements = new ArrayList<>();
     private List<Connections> connections = new ArrayList<>();
     private List<PathRequest> pathRequest = new ArrayList<>();
@@ -118,9 +117,9 @@ public class ExtractTopoDataStoreImpl {
      * Construct the ExtractTopoDataStoreImpl.
      */
     @SuppressWarnings("unchecked")
-    public ExtractTopoDataStoreImpl(final DataBroker dataBroker, PathComputationRequestInput input, AToZDirection atoz,
-            Long requestId) {
-        this.dataBroker = dataBroker;
+    public ExtractTopoDataStoreImpl(final NetworkTransactionService networkTransactionService,
+            PathComputationRequestInput input,AToZDirection atoz, Long requestId) {
+        this.networkTransactionService = networkTransactionService;
         Map<String, List<?>> map = extractTopo();
         if (map.containsKey("Elements")) {
             elements = (List<Elements>) map.get("Elements");
@@ -137,9 +136,9 @@ public class ExtractTopoDataStoreImpl {
         synchronization = extractSynchronization(requestId);
     }
 
-    public ExtractTopoDataStoreImpl(final DataBroker dataBroker, PathComputationRequestInput input, ZToADirection ztoa,
-            Long requestId) {
-        this.dataBroker = dataBroker;
+    public ExtractTopoDataStoreImpl(final NetworkTransactionService networkTransactionService,
+            PathComputationRequestInput input, ZToADirection ztoa, Long requestId) {
+        this.networkTransactionService = networkTransactionService;
         Map<String, List<?>> map = extractTopo();
         if (map.containsKey("Elements")) {
             elements = (List<Elements>) map.get("Elements");
@@ -174,15 +173,14 @@ public class ExtractTopoDataStoreImpl {
         InstanceIdentifier<Network> insIdrOpenRoadmNet = InstanceIdentifier
                 .builder(Networks.class)
                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID))).build();
-        ReadOnlyTransaction readOnlyTransaction = this.dataBroker.newReadOnlyTransaction();
         // Read the data broker
         try {
-            // Initialize the reading of the data broker
+            // Initialize the reading of the networkTransactionService
             // read the configuration part of the data broker that concerns
             // the openRoadm topology and get all the nodes
-            java.util.Optional<Network> openRoadmTopo = readOnlyTransaction
+            java.util.Optional<Network> openRoadmTopo = this.networkTransactionService
                     .read(LogicalDatastoreType.CONFIGURATION, insIdOpenRoadmTopo).get().toJavaUtil();
-            java.util.Optional<Network> openRoadmNet = readOnlyTransaction
+            java.util.Optional<Network> openRoadmNet = this.networkTransactionService
                     .read(LogicalDatastoreType.CONFIGURATION, insIdrOpenRoadmNet).get().toJavaUtil();
             if (openRoadmNet.isPresent()) {
                 List<Node> openRoadmNetNodeList = openRoadmNet.get().getNode();
@@ -387,9 +385,9 @@ public class ExtractTopoDataStoreImpl {
             }
         } catch (InterruptedException | ExecutionException e) {
             LOG.error("Error reading the topology", e);
-            readOnlyTransaction.close();
+            this.networkTransactionService.close();
         }
-        readOnlyTransaction.close();
+        this.networkTransactionService.close();
         map.put("Elements", topoElements);
         map.put("Connections", topoConnections);
         return map;
index 338624a2d1a60a85ffc29c3603faff1a2abf1af5..4aa3131b88cabc311fc42dfbde472cd86a8d1e8a 100644 (file)
@@ -149,8 +149,9 @@ public class GnpyResult {
                 NoPathCase noPathCase = (NoPathCase) response.getResponseType();
                 String noPathType = noPathCase.getNoPath().getNoPath();
                 LOG.info("GNPy: No path - {}",noPathType);
-                if (((noPathType == "NO_FEASIBLE_BAUDRATE_WITH_SPACING") && (noPathType == "NO_FEASIBLE_MODE"))
-                        && ((noPathType ==  "MODE_NOT_FEASIBLE") && (noPathType == "NO_SPECTRUM"))) {
+                if (((noPathType.equals("NO_FEASIBLE_BAUDRATE_WITH_SPACING"))
+                        && (noPathType.equals("NO_FEASIBLE_MODE"))) && ((noPathType.equals("MODE_NOT_FEASIBLE"))
+                        && (noPathType.equals("NO_SPECTRUM")))) {
                     List<PathMetric> pathMetricList = noPathCase.getNoPath().getPathProperties().getPathMetric();
                     LOG.info("GNPy : path is not feasible : {}", noPathType);
                     for (PathMetric pathMetric : pathMetricList) {
index c25f82d330c69e199d3782983f666a7eb1d5d7ab..212985aa303285cab46527b3394da5fdfa8f8465 100644 (file)
@@ -21,7 +21,6 @@ import java.util.Optional;
 
 import javassist.ClassPool;
 
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator;
 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
@@ -30,6 +29,7 @@ import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.transportpce.common.DataStoreContext;
 import org.opendaylight.transportpce.common.converter.XMLDataObjectConverter;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
 import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -53,7 +53,7 @@ public class ServiceDataStoreOperationsImpl implements ServiceDataStoreOperation
 
     private static final Logger LOG = LoggerFactory.getLogger(ServiceDataStoreOperationsImpl.class);
 
-    public ServiceDataStoreOperationsImpl(DataBroker dataBroker) {
+    public ServiceDataStoreOperationsImpl(NetworkTransactionService networkTransactionService) {
     }
 
     public void createXMLFromDevice(DataStoreContext dataStoreContextUtil, OrgOpenroadmDevice device, String output) {
diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/graph/InAlgoPathValidator.java b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/InAlgoPathValidator.java
new file mode 100644 (file)
index 0000000..19f6049
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright Â© 2017 AT&T, 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.pce.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.shortestpath.PathValidator;
+import org.opendaylight.transportpce.pce.constraints.PceConstraints;
+import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InAlgoPathValidator implements PathValidator<String, PceGraphEdge> {
+    /* Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(PceGraph.class);
+
+    private PceConstraints pceHardConstraints = null;
+    private PceNode zendNode = null;
+
+    public InAlgoPathValidator(PceConstraints pceHardConstraints, PceNode zendNode) {
+        super();
+        this.pceHardConstraints = pceHardConstraints;
+        this.zendNode = zendNode;
+    }
+
+    @Override
+    public boolean isValidPath(GraphPath<String, PceGraphEdge> partialPath, PceGraphEdge edge) {
+        int size = partialPath.getEdgeList().size();
+        if (size == 0) {
+            return true;
+        }
+        LOG.debug("InAlgoPathValidator: partialPath size: {} prev edge {} new edge {}",
+            size, edge.link().getlinkType(), partialPath.getEdgeList().get(size - 1).link().getlinkType());
+
+        if (!checkTurn(partialPath.getEdgeList().get(size - 1).link().getlinkType(), edge.link().getlinkType())) {
+            return false;
+        }
+        if (!checkLimits(partialPath, edge, pceHardConstraints)) {
+            return false;
+        }
+        if (!checkInclude(partialPath, edge, zendNode, pceHardConstraints)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean checkTurn(OpenroadmLinkType prevType, OpenroadmLinkType nextType) {
+
+        if (nextType == OpenroadmLinkType.ADDLINK && prevType != OpenroadmLinkType.XPONDEROUTPUT) {
+            LOG.debug("in checkPath dropped {} {} ", prevType, nextType);
+            return false;
+        }
+
+        if (nextType == OpenroadmLinkType.EXPRESSLINK && prevType != OpenroadmLinkType.ROADMTOROADM) {
+            LOG.debug("in checkPath dropped {} {} ", prevType, nextType);
+            return false;
+        }
+
+        if (nextType == OpenroadmLinkType.DROPLINK && prevType != OpenroadmLinkType.ROADMTOROADM) {
+            LOG.debug("in checkPath dropped {} {} ", prevType, nextType);
+            return false;
+        }
+
+        if (nextType == OpenroadmLinkType.XPONDERINPUT && prevType != OpenroadmLinkType.DROPLINK) {
+            LOG.debug("in checkPath dropped {} {} ", prevType, nextType);
+            return false;
+        }
+
+        if (prevType == OpenroadmLinkType.EXPRESSLINK && nextType != OpenroadmLinkType.ROADMTOROADM) {
+            LOG.debug("in checkPath dropped {} {} ", prevType, nextType);
+            return false;
+        }
+
+        if (prevType == OpenroadmLinkType.ADDLINK && nextType != OpenroadmLinkType.ROADMTOROADM) {
+            LOG.debug("in checkPath dropped {} {} ", prevType, nextType);
+            return false;
+        }
+
+        return true;
+    }
+
+    /*
+     * this method should be added to JgraphT as accumulated values inside path
+     * (RankingPathElementList)
+     */
+    private boolean checkLimits(GraphPath<String, PceGraphEdge> partialPath,
+                                PceGraphEdge edge, PceConstraints pceHardConstraintsInput) {
+
+        Long latencyConstraint = pceHardConstraintsInput.getMaxLatency();
+        if (latencyConstraint > 0) {
+            long newLatency = Math.round(calcLatency(partialPath) + edge.link().getLatency());
+            if (newLatency > latencyConstraint) {
+                LOG.warn("In validateLatency: AtoZ path is dropped because of MAX LATENCY {} > {}",
+                    newLatency, latencyConstraint);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private double calcLatency(GraphPath<String, PceGraphEdge> path) {
+        double latency = 0;
+        for (PceGraphEdge edge : path.getEdgeList()) {
+            latency = latency + edge.link().getLatency();
+        }
+        return latency;
+    }
+
+    /*
+     * checkInclude this method ensures the path is going over path elements
+     * to be included, alway check target node in the new edge
+     *
+     */
+    private boolean checkInclude(GraphPath<String, PceGraphEdge> partialPath,
+                                 PceGraphEdge edge, PceNode zendNodeInput,
+                                 PceConstraints pceHardConstraintsInput) {
+
+        List<ResourcePair> listToInclude = pceHardConstraintsInput.getListToInclude();
+        if (listToInclude.isEmpty()) {
+            return true;
+        }
+
+        // run this check only for the last edge of path
+        if (!edge.link().getDestId().getValue().equals(zendNodeInput.getNodeId().getValue())) {
+            return true;
+        }
+        List<PceGraphEdge> pathEdges = partialPath.getEdgeList();
+        pathEdges.add(edge);
+        LOG.info(" in checkInclude vertex list: [{}]", partialPath.getVertexList());
+
+        List<String> listOfElementsSubNode = new ArrayList<String>();
+        listOfElementsSubNode.add(pathEdges.get(0).link().getsourceSupNodeId());
+        listOfElementsSubNode.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.NODE));
+
+        List<String> listOfElementsCLLI = new ArrayList<String>();
+        listOfElementsCLLI.add(pathEdges.get(0).link().getsourceCLLI());
+        listOfElementsCLLI.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.CLLI));
+
+        List<String> listOfElementsSRLG = new ArrayList<String>();
+        listOfElementsSRLG.add("NONE"); // first link is XPONDEROUTPUT, no SRLG for it
+        listOfElementsSRLG.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.SRLG));
+
+        // validation: check each type for each element
+        for (ResourcePair next : listToInclude) {
+            int indx = -1;
+            switch (next.type) {
+                case NODE:
+                    if (listOfElementsSubNode.contains(next.name)) {
+                        indx = listOfElementsSubNode.indexOf(next.name);
+                    }
+                    break;
+                case SRLG:
+                    if (listOfElementsSRLG.contains(next.name)) {
+                        indx = listOfElementsSRLG.indexOf(next.name);
+                    }
+                    break;
+                case CLLI:
+                    if (listOfElementsCLLI.contains(next.name)) {
+                        indx = listOfElementsCLLI.indexOf(next.name);
+                    }
+                    break;
+                default:
+                    LOG.warn(" in checkInclude vertex list unsupported resource type: [{}]", next.type);
+            }
+
+            if (indx < 0) {
+                LOG.debug(" in checkInclude stopped : {} ", next.name);
+                return false;
+            }
+
+            LOG.debug(" in checkInclude next found {} in {}", next.name, partialPath.getVertexList());
+
+            listOfElementsSubNode.subList(0, indx).clear();
+            listOfElementsCLLI.subList(0, indx).clear();
+            listOfElementsSRLG.subList(0, indx).clear();
+        }
+
+        LOG.info(" in checkInclude passed : {} ", partialPath.getVertexList());
+        return true;
+    }
+
+    private List<String> listOfElementsBuild(List<PceGraphEdge> pathEdges, PceConstraints.ResourceType type) {
+        List<String> listOfElements = new ArrayList<String>();
+
+        for (PceGraphEdge link: pathEdges) {
+            switch (type) {
+                case NODE:
+                    listOfElements.add(link.link().getdestSupNodeId());
+                    break;
+                case CLLI:
+                    listOfElements.add(link.link().getdestCLLI());
+                    break;
+                case SRLG:
+                    if (link.link().getlinkType() != OpenroadmLinkType.ROADMTOROADM) {
+                        listOfElements.add("NONE");
+                        break;
+                    }
+
+                    // srlg of link is List<Long>. But in this algo we need string representation of one SRLG
+                    // this should be any SRLG mentioned in include constraints if any of them if mentioned
+                    boolean found = false;
+                    for (Long srlg : link.link().getsrlgList()) {
+                        String srlgStr = String.valueOf(srlg);
+                        if (pceHardConstraints.getSRLGnames().contains(srlgStr)) {
+                            listOfElements.add(srlgStr);
+                            LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link().toString());
+                            found = true;
+                            continue;
+                        }
+                    }
+                    if (found == false) {
+                        // there is no specific srlg to include. thus add to list just the first one
+                        listOfElements.add("NONE");
+                    }
+                    break;
+                default:
+                    LOG.debug("listOfElementsBuild unsupported resource type");
+            }
+        }
+
+        return listOfElements;
+    }
+}
index 08886ca87e2532c1216e69b554e9e6fbb8277273..0aeadeb292ec63ddc91e97a5e21b46b24e0886ae 100644 (file)
@@ -6,30 +6,36 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.transportpce.pce;
+package org.opendaylight.transportpce.pce.graph;
 
-import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;
-import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import org.apache.commons.collections15.Transformer;
+
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.shortestpath.KShortestPaths;
+import org.jgrapht.alg.shortestpath.PathValidator;
+import org.jgrapht.graph.DefaultDirectedWeightedGraph;
 import org.opendaylight.transportpce.common.ResponseCodes;
-import org.opendaylight.transportpce.pce.PceResult.LocalCause;
+import org.opendaylight.transportpce.pce.constraints.PceConstraints;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceLink;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceResult.LocalCause;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 public class PceGraph {
     /* Logging. */
-    private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
+    private static final Logger LOG = LoggerFactory.getLogger(PceGraph.class);
 
     ////////////////////////// for Graph ///////////////////////////
-    private DirectedSparseMultigraph<PceNode, PceLink> nwGraph = new DirectedSparseMultigraph<PceNode, PceLink>();
-    private DijkstraShortestPath<PceNode, PceLink> shortestPath = null;
+    int kpathsToBring = 10; // how many paths to bring
+    int mhopsPerPath = 50; // max #hops
 
     // input
     private Map<NodeId, PceNode> allPceNodes = new HashMap<NodeId, PceNode>();
@@ -43,20 +49,10 @@ public class PceGraph {
     private PceResult pceResult = null;
     private List<PceLink> shortestPathAtoZ = null;
 
-    // TODO hard-coded 96
-    private static final int MAX_WAWELENGTH = 96;
-
     // for path calculation
-    private List<PceLink> pathAtoZ = null;
-    private int minFoundDistance;
-    private int tmpAtozDistance = 0;
-    private int tmpAtozLatency = 0;
-    private int bestDistance;
-    private boolean noPathExists = false;
+    List<GraphPath<String, PceGraphEdge>> allWPaths = null;
 
-    private boolean foundButTooHighLatency = false;
-
-    private List<ListOfNodes> listOfNodesPerWL = new ArrayList<ListOfNodes>();
+    private List<PceLink> pathAtoZ = new ArrayList<PceLink>();
 
     public PceGraph(PceNode aendNode, PceNode zendNode, Map<NodeId, PceNode> allPceNodes,
             PceConstraints pceHardConstraints, PceConstraints pceSoftConstraints, PceResult pceResult) {
@@ -68,373 +64,199 @@ public class PceGraph {
         this.pceHardConstraints = pceHardConstraints;
         this.pceSoftConstraints = pceSoftConstraints;
 
-        // TODO - fix the assumption that wavelengths are from 1 to 96 and can be used
-        // as index
-        this.listOfNodesPerWL.add(new ListOfNodes());
-        for (int i = 1; i <= MAX_WAWELENGTH; i++) {
-            // create list of nodes per wavelength
-            ListOfNodes wls = new ListOfNodes();
-            this.listOfNodesPerWL.add(wls);
-        }
+        LOG.info("In GraphCalculator: A and Z = {} / {} ", aendNode.toString(), zendNode.toString());
+        LOG.debug("In GraphCalculator: allPceNodes size {}, nodes {} ", allPceNodes.size(), allPceNodes.toString());
+
+        // PceCalculation.printNodesInfo(allPceNodes);
 
-        LOG.debug("In GraphCalculator: A and Z = {} / {}", aendNode.toString(), zendNode.toString());
-        LOG.debug("In GraphCalculator: allPceNodes = {}", allPceNodes.toString());
     }
 
     public boolean calcPath() {
 
-        LOG.info("In calcPath: metric {} is used ", this.pceHardConstraints.getPceMetrics());
+        LOG.info(" In PCE GRAPH calcPath : K SHORT PATHS algorithm ");
 
-        populateGraph(this.allPceNodes);
+        DefaultDirectedWeightedGraph<String, PceGraphEdge> weightedGraph =
+                new DefaultDirectedWeightedGraph<String, PceGraphEdge>(PceGraphEdge.class);
+        populateWithNodes(weightedGraph);
+        populateWithLinks(weightedGraph);
 
-        LOG.info(" In PCE GRAPH : QUICK algorithm ");
-
-        // quick algorithm
-        if (runGraph()) {
-
-            this.bestDistance = this.tmpAtozDistance;
-
-            if (chooseWavelength()) {
-                this.pceResult.setRC(ResponseCodes.RESPONSE_OK);
-                this.shortestPathAtoZ = this.pathAtoZ;
-                LOG.info("In GraphCalculator QUICK CalcPath: AtoZ {}", this.pathAtoZ.toString());
-                LOG.info("In GraphCalculator QUICK CalcPath: pceResult {}", this.pceResult.toString());
-                return true;
-            }
-
-            // continue work per wavelength
-            LOG.warn(" In PCE GRAPH : QUICK algorithm didn't find shared wavelength over the shortest path");
-
-        }
-
-        LOG.warn(" In PCE GRAPH : QUICK algorithm didn't find shortest path with single wavelength");
-        if (this.noPathExists) {
-            // quick algo looks for path independently on wavelength. therefore no path
-            // means fatal problem
-            LOG.warn(" In PCE GRAPH : QUICK algorithm didn't find any path");
-            this.pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+        if (!runKgraphs(weightedGraph)) {
+            LOG.info("In calcPath : pceResult {}", pceResult.toString());
             return false;
         }
 
-        // rearrange all nodes per the relevant wavelength indexes
-        extractWLs(this.allPceNodes);
-
-        this.pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
-        boolean firstPath = true;
+        // validate found paths
+        pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+        for (GraphPath<String, PceGraphEdge> path : allWPaths) {
 
-        for (int i = 1; i <= MAX_WAWELENGTH; i++) {
-            LOG.info(" In PCE GRAPH : FUll algorithm for WL {}", i);
-            List<PceNode> nodes = this.listOfNodesPerWL.get(i).getNodes();
-            populateGraph(nodes);
+            PostAlgoPathValidator papv = new PostAlgoPathValidator();
+            pceResult = papv.checkPath(path, allPceNodes, pceResult);
+            LOG.info("In calcPath after PostAlgoPathValidator {} {}",
+                    pceResult.getResponseCode(), ResponseCodes.RESPONSE_OK);
 
-            if (!runGraph()) {
+            if (!pceResult.getResponseCode().equals(ResponseCodes.RESPONSE_OK)) {
+                LOG.info("In calcPath: post algo validations DROPPED the path {}", path.toString());
                 continue;
             }
 
-            if (firstPath) {
-                // set minFoundDistance for the first time
-                rememberPath(i);
-                firstPath = false;
-            }
-
-            if (this.tmpAtozDistance < this.minFoundDistance) {
-                rememberPath(i);
+            // build pathAtoZ
+            pathAtoZ.clear();
+            for (PceGraphEdge edge : path.getEdgeList()) {
+                pathAtoZ.add(edge.link());
             }
 
-            if (this.tmpAtozDistance == this.bestDistance) {
-                // optimization: stop on the first WL with result == the best
-                break;
-            }
+            shortestPathAtoZ = new ArrayList<>(pathAtoZ);
+            LOG.info("In calcPath Path FOUND path for wl [{}], hops {}, distance per metrics {}, path AtoZ {}",
+                    pceResult.getResultWavelength(), pathAtoZ.size(), path.getWeight(), pathAtoZ.toString());
+            break;
         }
 
-        // return codes can come in different orders. this method fixes it a bit
-        // TODO build it better
-        analyzeResult();
-
-        LOG.info("In GraphCalculator FUll CalcPath: pceResult {}", this.pceResult.toString());
-        return (this.pceResult.getStatus());
-    }
-
-    private boolean populateGraph(Map<NodeId, PceNode> allNodes) {
-
-        cleanupGraph();
-        Iterator<Map.Entry<NodeId, PceNode>> nodes = allNodes.entrySet().iterator();
-        while (nodes.hasNext()) {
-            Map.Entry<NodeId, PceNode> node = nodes.next();
-            PceNode pcenode = node.getValue();
-            List<PceLink> links = pcenode.getOutgoingLinks();
-            LOG.info("In populateGraph: use node for graph {}", pcenode.toString());
-            for (PceLink link : links) {
-                LOG.info("In populateGraph: add edge to graph {}", link.toString());
-                addLinkToGraph(link);
-            }
+        if (shortestPathAtoZ != null) {
+            LOG.info("In calcPath CHOOSEN PATH for wl [{}], hops {}, path AtoZ {}",
+                    pceResult.getResultWavelength(), shortestPathAtoZ.size(), shortestPathAtoZ.toString());
         }
-        return true;
+        LOG.info("In calcPath : pceResult {}", pceResult.toString());
+        return (pceResult.getStatus());
     }
 
-    private boolean populateGraph(List<PceNode> allNodes) {
-
-        cleanupGraph();
-
-        for (PceNode node : allNodes) {
-            List<PceLink> links = node.getOutgoingLinks();
-            LOG.debug("In populateGraph: use node for graph {}", node.toString());
-            for (PceLink link : links) {
-                LOG.debug("In populateGraph: add edge to graph {}", link.toString());
-                addLinkToGraph(link);
-            }
+    private boolean runKgraphs(DefaultDirectedWeightedGraph<String, PceGraphEdge> weightedGraph) {
 
+        if (weightedGraph.edgeSet().isEmpty() || weightedGraph.vertexSet().isEmpty()) {
+            return false;
         }
 
-        return true;
-    }
-
-    private boolean runGraph() {
-        LOG.info("In runGraph Vertices: {}; Eges: {} ", this.nwGraph.getVertexCount(), this.nwGraph.getEdgeCount());
-
-        this.pathAtoZ = null;
+        PathValidator<String, PceGraphEdge> wpv = new InAlgoPathValidator(pceHardConstraints, zpceNode);
 
-        try {
-            this.shortestPath = calcAlgo();
-
-            if (this.shortestPath == null) {
-                this.noPathExists = true;
-                LOG.error("In runGraph: shortest path alg is null ");// ,
-                return false;
-            }
-
-            this.pathAtoZ = this.shortestPath.getPath(this.apceNode, this.zpceNode);
-
-            if ((this.pathAtoZ == null) || (this.pathAtoZ.size() == 0)) {
-                LOG.info("In runGraph: AtoZ path is empty");
-                this.pceResult.setLocalCause(LocalCause.NO_PATH_EXISTS);
-                return false;
-            }
+        // local optimization. if 'include' constraint exists then increase amount of paths to return.
+        // it's because this constraint is checked at the last step when part of good paths
+        // are dropped by other constraints
+        if (!pceHardConstraints.getListToInclude().isEmpty()) {
+            kpathsToBring = kpathsToBring * 10;
+            LOG.info("k = {}",kpathsToBring);
+        }
 
-            pathMetricsToCompare();
+        // KShortestPaths on weightedGraph
+        KShortestPaths<String, PceGraphEdge> swp =
+            new KShortestPaths<String, PceGraphEdge>(weightedGraph, kpathsToBring, mhopsPerPath, wpv);
 
-            return compareMaxLatency();
+        allWPaths = swp.getPaths(apceNode.getNodeId().getValue(), zpceNode.getNodeId().getValue());
 
-        } catch (IllegalArgumentException e) {
-            LOG.error("In runGraph: can't calculate the path. A or Z node don't have any links {}", e);
-            this.noPathExists = true;
+        if (allWPaths.isEmpty()) {
+            LOG.info(" In runKgraphs : algorithm didn't find any path");
+            pceResult.setLocalCause(LocalCause.NO_PATH_EXISTS);
+            pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
             return false;
-
         }
-    }
-
-    private DijkstraShortestPath<PceNode, PceLink> calcAlgo() {
-
-        Transformer<PceLink, Double> wtTransformer = new Transformer<PceLink, Double>() {
-            @Override
-            public Double transform(PceLink link) {
-                return link.getLatency();
-            }
-        };
-
-        this.shortestPath = null;
 
-        switch (this.pceHardConstraints.getPceMetrics()) {
-            case PropagationDelay:
-                this.shortestPath = new DijkstraShortestPath<>(this.nwGraph, wtTransformer);
-                LOG.debug("In calcShortestPath: PropagationDelay method run ");
-                break;
-            case HopCount:
-                this.shortestPath = new DijkstraShortestPath<>(this.nwGraph);
-                LOG.debug("In calcShortestPath: HopCount method run ");
-                break;
-
-            default:
-                this.shortestPath = new DijkstraShortestPath<>(this.nwGraph);
-                LOG.warn("In calcShortestPath: instead IGPMetric/TEMetric method Hop-Count runs as a default ");
-                break;
+        // debug print
+        for (GraphPath<String, PceGraphEdge> path : allWPaths) {
+            LOG.info("path Weight: {} : {}", path.getWeight(), path.getVertexList().toString());
         }
+        // debug print
 
-        return this.shortestPath;
-
+        return true;
     }
 
-    private void addLinkToGraph(PceLink pcelink) {
+    private boolean validateLinkforGraph(PceLink pcelink) {
 
-        PceNode source = this.allPceNodes.get(pcelink.getSourceId());
-        PceNode dest = this.allPceNodes.get(pcelink.getDestId());
+        PceNode source = allPceNodes.get(pcelink.getSourceId());
+        PceNode dest = allPceNodes.get(pcelink.getDestId());
 
         if (source == null) {
-            LOG.error("In addLinkToGraph link source node is null  :   {}", pcelink.toString());
-            return;
+            LOG.error("In addLinkToGraph link source node is null : {}", pcelink.toString());
+            return false;
         }
         if (dest == null) {
-            LOG.error("In addLinkToGraph link dest node is null  :   {}", pcelink.toString());
-            return;
-        }
-
-        LOG.debug("In addLinkToGraph link and nodes :  {} ; {} / {}", pcelink.toString(), source.toString(),
-                dest.toString());
-        this.nwGraph.addEdge(pcelink, source, dest);
-
-    }
-
-    /*
-     * "QUICK" approach build shortest path. and then look for a single wavelength
-     * on it
-     */
-    private boolean chooseWavelength() {
-        for (long i = 1; i <= MAX_WAWELENGTH; i++) {
-            boolean completed = true;
-            for (PceLink link : this.pathAtoZ) {
-                PceNode pceNode = this.allPceNodes.get(link.getSourceId());
-                if (!pceNode.checkWL(i)) {
-                    completed = false;
-                    break;
-                }
-            }
-            if (completed) {
-                this.pceResult.setResultWavelength(i);
-                break;
-            }
+            LOG.error("In addLinkToGraph link dest node is null : {}", pcelink.toString());
+            return false;
         }
-        return (this.pceResult.getResultWavelength() > 0);
-    }
 
-    public List<PceLink> getPathAtoZ() {
-        return this.shortestPathAtoZ;
-    }
+        LOG.debug("In addLinkToGraph link to nodes : {}{} {}", pcelink.toString(), source.toString(), dest.toString());
+        return true;
 
-    public PceResult getReturnStructure() {
-        return this.pceResult;
     }
 
-    // TODO build ordered set ordered per the index. Current assumption is that
-    // wavelenght serves as an index
-    private class ListOfNodes {
-        private List<PceNode> listOfNodes = new ArrayList<PceNode>();
-
-        private void addNodetoWL(PceNode node) {
-            this.listOfNodes.add(node);
-        }
-
-        private List<PceNode> getNodes() {
-            return this.listOfNodes;
+    private void populateWithNodes(DefaultDirectedWeightedGraph<String, PceGraphEdge> weightedGraph) {
+        Iterator<Map.Entry<NodeId, PceNode>> nodes = allPceNodes.entrySet().iterator();
+        while (nodes.hasNext()) {
+            Map.Entry<NodeId, PceNode> node = nodes.next();
+            weightedGraph.addVertex(node.getValue().getNodeId().getValue());
+            LOG.debug("In populateWithNodes in node :  {}", node.getValue().toString());
         }
-
     }
 
-    private boolean extractWLs(Map<NodeId, PceNode> allNodes) {
+    private boolean populateWithLinks(DefaultDirectedWeightedGraph<String, PceGraphEdge> weightedGraph) {
 
-        Iterator<Map.Entry<NodeId, PceNode>> nodes = allNodes.entrySet().iterator();
+        Iterator<Map.Entry<NodeId, PceNode>> nodes = allPceNodes.entrySet().iterator();
         while (nodes.hasNext()) {
 
             Map.Entry<NodeId, PceNode> node = nodes.next();
 
             PceNode pcenode = node.getValue();
-            List<Long> wls = pcenode.getAvailableWLs();
-
-            LOG.debug("In extractWLs wls in node : {} {}", pcenode.toString(), wls.size());
-            LOG.debug("In extractWLs listOfWLs total :   {}", this.listOfNodesPerWL.size());
-            for (Long i : wls) {
-                LOG.debug("In extractWLs i in wls :  {}", i);
-                ListOfNodes lwl = this.listOfNodesPerWL.get(i.intValue());
-                lwl.addNodetoWL(pcenode);
-            }
-        }
-
-        return true;
-    }
-
-    private void cleanupGraph() {
-        LOG.debug("In cleanupGraph remove {} nodes ", this.nwGraph.getEdgeCount());
-        Iterable<PceNode> toRemove = new ArrayList<PceNode>(this.nwGraph.getVertices());
-        for (PceNode node : toRemove) {
-            this.nwGraph.removeVertex(node);
-        }
-        LOG.debug("In cleanupGraph after {} removed ", this.nwGraph.getEdgeCount());
-    }
-
-    private void analyzeResult() {
-        // very simple for the start
+            List<PceLink> links = pcenode.getOutgoingLinks();
 
-        if (this.pceResult.getStatus()) {
-            return;
-        }
+            LOG.debug("In populateGraph: use node for graph {}", pcenode.toString());
 
-        // if request is rejected but at least once there was path found, try to save
-        // the real reason of reject
-        if (this.foundButTooHighLatency) {
-            this.pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
-            this.pceResult.setLocalCause(LocalCause.TOO_HIGH_LATENCY);
-            this.pceResult.setCalcMessage("No path available due to constraint Hard/Latency");
-        }
-        return;
-    }
+            for (PceLink link : links) {
+                LOG.debug("In populateGraph node {} : add edge to graph {}", pcenode.toString(), link.toString());
 
-    private boolean compareMaxLatency() {
+                if (!validateLinkforGraph(link)) {
+                    continue;
+                }
 
-        Long latencyConstraint = this.pceHardConstraints.getMaxLatency();
+                PceGraphEdge graphLink = new PceGraphEdge(link);
+                weightedGraph.addEdge(link.getSourceId().getValue(), link.getDestId().getValue(), graphLink);
 
-        if ((latencyConstraint > 0) && (this.tmpAtozLatency > latencyConstraint)) {
-            this.foundButTooHighLatency = true;
-            this.pceResult.setLocalCause(LocalCause.TOO_HIGH_LATENCY);
-            LOG.info("In validateLatency: AtoZ path has too high LATENCY {} > {}", this.tmpAtozLatency,
-                latencyConstraint);
-            return false;
+                weightedGraph.setEdgeWeight(graphLink, chooseWeight(link));
+            }
         }
-        LOG.info("In validateLatency: AtoZ path  is {}", this.pathAtoZ.toString());
         return true;
     }
 
-    private void pathMetricsToCompare() {
-
-        this.tmpAtozDistance = this.shortestPath.getDistance(this.apceNode, this.zpceNode).intValue();
+    private double chooseWeight(PceLink link) {
 
-        // TODO this code is for HopCount. excluded from switch for not implemented
-        // IGPMetric and TEMetric
-        this.tmpAtozLatency = 0;
-        for (PceLink pcelink : this.pathAtoZ) {
-            this.tmpAtozLatency = this.tmpAtozLatency + pcelink.getLatency().intValue();
-        }
-
-        switch (this.pceHardConstraints.getPceMetrics()) {
-            case IGPMetric:
-                // TODO implement IGPMetric - low priority
-                LOG.error("In PceGraph not implemented IGPMetric. HopCount works as a default");
+        // HopCount is default
+        double weight = 1;
+        switch (pceHardConstraints.getPceMetrics()) {
+            case IGPMetric :
+                // TODO implement IGPMetric - low priority.
+                LOG.warn("In PceGraph not implemented IGPMetric. HopCount works as a default");
                 break;
 
-            case TEMetric:
+            case TEMetric :
                 // TODO implement TEMetric - low priority
-                LOG.error("In PceGraph not implemented TEMetric. HopCount works as a default");
+                LOG.warn("In PceGraph not implemented TEMetric. HopCount works as a default");
                 break;
 
-            case HopCount:
+            case HopCount :
+                weight = 1;
+                LOG.debug("In PceGraph HopCount is used as a metrics. {}", link.toString());
                 break;
 
-            case PropagationDelay:
-                this.tmpAtozLatency = this.tmpAtozDistance;
+            case PropagationDelay :
+                weight = link.getLatency();
+                LOG.debug("In PceGraph PropagationDelay is used as a metrics. {}", link.toString());
                 break;
 
             default:
-                LOG.error("In PceGraph {}: unknown metric. ", this.pceHardConstraints.getPceMetrics());
                 break;
         }
 
-        LOG.info("In runGraph: AtoZ size {}, distance {}, latency {} ", this.pathAtoZ.size(), this.tmpAtozDistance,
-                this.tmpAtozLatency);
-        LOG.debug("In runGraph: AtoZ {}", this.pathAtoZ.toString());
-
-        return;
+        return weight;
     }
 
-    private void rememberPath(int index) {
-        this.minFoundDistance = this.tmpAtozDistance;
-        this.shortestPathAtoZ = this.pathAtoZ;
-        this.pceResult.setResultWavelength(Long.valueOf(index));
-        this.pceResult.setRC(ResponseCodes.RESPONSE_OK);
-        LOG.info("In GraphCalculator FUll CalcPath for wl [{}]: found AtoZ {}", index, this.pathAtoZ.toString());
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public List<PceLink> getPathAtoZ() {
+        return shortestPathAtoZ;
+    }
 
+    public PceResult getReturnStructure() {
+        return pceResult;
     }
 
-    public void setConstrains(PceConstraints pceHardConstraintsIn, PceConstraints pceSoftConstraintsIn) {
-        this.pceHardConstraints = pceHardConstraintsIn;
-        this.pceSoftConstraints = pceSoftConstraintsIn;
+    public void setConstrains(PceConstraints pceHardConstraintsInput, PceConstraints pceSoftConstraintsInput) {
+        this.pceHardConstraints = pceHardConstraintsInput;
+        this.pceSoftConstraints = pceSoftConstraintsInput;
     }
 
 }
diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraphEdge.java b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraphEdge.java
new file mode 100644 (file)
index 0000000..78861c5
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright Â© 2017 AT&T, 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.pce.graph;
+
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceLink;
+
+public class PceGraphEdge extends DefaultWeightedEdge {
+
+    private static final long serialVersionUID = 1L;
+    private PceLink link;
+
+    public PceGraphEdge(PceLink link) {
+        super();
+        this.link = link;
+    }
+
+    public PceLink link() {
+        return link;
+    }
+
+}
diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java
new file mode 100644 (file)
index 0000000..55ea21b
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright Â© 2017 AT&T, 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.pce.graph;
+
+import java.util.Map;
+
+import org.jgrapht.GraphPath;
+import org.opendaylight.transportpce.common.ResponseCodes;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PostAlgoPathValidator {
+    /* Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(PceGraph.class);
+
+    // TODO hard-coded 96
+    private static final int MAX_WAWELENGTH = 96;
+
+    public PceResult checkPath(GraphPath<String, PceGraphEdge> path,
+            Map<NodeId, PceNode> allPceNodes, PceResult pceResult) {
+
+        if (path.getEdgeList().size() == 0) {
+            pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+            return pceResult;
+        }
+
+        // choose wavelength available in all nodes of the path
+        pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+        Long waveL = chooseWavelength(path, allPceNodes);
+        if (waveL > 0) {
+            pceResult.setResultWavelength(waveL);
+            pceResult.setRC(ResponseCodes.RESPONSE_OK);
+            LOG.info("In PostAlgoPathValidator: chooseWavelength WL found {} {}", waveL, path.toString());
+        }
+
+        // TODO here other post algo validations can be added
+        // more data can be sent to PceGraph module via PceResult structure if
+        // required
+        stubCheckOSNR(path);
+
+        return pceResult;
+    }
+
+    private Long chooseWavelength(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
+        Long wavelength = -1L;
+
+        for (long i = 1; i <= MAX_WAWELENGTH; i++) {
+            boolean completed = true;
+            LOG.debug("In chooseWavelength: {} {}", path.getLength(), path.toString());
+            for (PceGraphEdge edge : path.getEdgeList()) {
+                LOG.debug("In chooseWavelength: source {} ", edge.link().getSourceId().toString());
+                PceNode pceNode = allPceNodes.get(edge.link().getSourceId());
+                if (!pceNode.checkWL(i)) {
+                    completed = false;
+                    break;
+                }
+            }
+            if (completed) {
+                wavelength = i;
+                break;
+            }
+        }
+        return wavelength;
+    }
+
+    private boolean stubCheckOSNR(GraphPath<String, PceGraphEdge> path) {
+        double localOsnr = 0L;
+        for (PceGraphEdge edge : path.getEdgeList()) {
+            localOsnr = localOsnr + edge.link().getosnr();
+        }
+        LOG.info("In OSNR Stub: {}", localOsnr);
+        return true;
+    }
+}
index f72385b9b17465acc3bada02cd1510e6d5284283..e201199c56417f185dc5a63540c1450c50646879 100644 (file)
@@ -56,8 +56,8 @@ public class PceServiceRPCImpl implements TransportpcePceService {
         try {
             output = this.pathComputationService.pathComputationRequest(input).get();
         } catch (InterruptedException | ExecutionException e) {
-            LOG.error("RPC cancelResourceReserve failed !", e);
+            LOG.error("RPC path computation request failed !", e);
         }
         return RpcResultBuilder.success(output).buildFuture();
     }
-}
+}
\ No newline at end of file
index d3985f00497893d842a02b562e2aad4c0ae45260..6ee3043d8a722afc95772a70d47a556426f4a491 100644 (file)
@@ -5,16 +5,20 @@
  * 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.pce;
+package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
+import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev181130.span.attributes.LinkConcatenation;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Link1;
+
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.link.oms.attributes.Span;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
 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.topology.rev180226.LinkId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -26,6 +30,49 @@ public final class MapUtils {
     private MapUtils() {
     }
 
+    public static void mapDiversityConstraints(List<Node> allNodes, List<Link> allLinks,
+            PceConstraints pceHardConstraints) {
+        List<String> excClliNodes = pceHardConstraints.getExcludeClliNodes();
+        List<String> excNodes = pceHardConstraints.getExcludeNodes();
+        List<String> excSrlgLinks = pceHardConstraints.getExcludeSrlgLinks();
+
+        LOG.info("mapDiversityConstraints before : ExcludeClliNodes {} \n ExcludeNodes {} \n ExcludeSrlgLinks {}",
+                excClliNodes.toString(), excNodes.toString(), excSrlgLinks.toString());
+
+        for (Node node : allNodes) {
+            if (excClliNodes.contains(node.getNodeId().getValue())) {
+                LOG.debug("mapDiversityConstraints setExcludeCLLI for node {}", node.getNodeId().getValue());
+                pceHardConstraints.setExcludeCLLI(Arrays.asList(getCLLI(node)));
+            }
+
+            if (excNodes.contains(node.getNodeId().getValue())) {
+                LOG.debug("mapDiversityConstraints setExcludeSupNodes for node {}", node.getNodeId().getValue());
+                pceHardConstraints.setExcludeSupNodes(Arrays.asList(getSupNode(node)));
+            }
+        }
+
+        for (Link link : allLinks) {
+            if (excSrlgLinks.contains(link.getLinkId().getValue())) {
+                // zero SRLG means not populated as not OMS link
+                List<Long> srlg = null;
+                if (calcType(link) == OpenroadmLinkType.ROADMTOROADM) {
+                    srlg = getSRLG(link);
+                    if (!srlg.isEmpty()) {
+                        pceHardConstraints.setExcludeSRLG(srlg);
+                        LOG.debug("mapDiversityConstraints setExcludeSRLG {} for link {}",
+                                srlg.toString(), link.getLinkId().getValue());
+                    }
+                }
+            }
+        }
+
+        LOG.info("mapDiversityConstraints after : ExcludeCLLI {} \n ExcludeSupNodes {} \n ExcludeSRLG {}",
+                pceHardConstraints.getExcludeCLLI().toString(),
+                pceHardConstraints.getExcludeSupNodes().toString(),
+                pceHardConstraints.getExcludeSRLG().toString());
+
+    }
+
     public static String getCLLI(Node node) {
         // TODO STUB retrieve CLLI from node. for now it is supporting node ID of the first supp node
         return node.getSupportingNode().get(0).getNodeRef().getValue();
@@ -33,14 +80,13 @@ public final class MapUtils {
 
     public static List<Long> getSRLG(Link link) {
         List<Long> srlgList = new ArrayList<Long>();
-        Span span = getOmsAttributesSpan(link);
-        if (span != null) {
-            List<LinkConcatenation> linkList = span.getLinkConcatenation();
+        try {
+            List<LinkConcatenation> linkList = getOmsAttributesSpan(link).getLinkConcatenation();
             for (LinkConcatenation lc : linkList) {
                 srlgList.add(lc.getSRLGId());
             }
-        } else {
-            LOG.error("MapUtils: No LinkConcatenation for link : {}", link);
+        } catch (NullPointerException e) {
+            LOG.debug("No concatenation for this link");
         }
         return srlgList;
     }
@@ -53,7 +99,7 @@ public final class MapUtils {
     public static OpenroadmLinkType calcType(Link link) {
         Link1 link1 = null;
         OpenroadmLinkType tmplType = null;
-
+        // ID and type
         link1 = link.augmentation(Link1.class);
         if (link1 == null) {
             LOG.error("MapUtils: No Link augmentation available. {}", link.getLinkId().getValue());
@@ -74,19 +120,29 @@ public final class MapUtils {
         link1 = link.augmentation(Link1.class);
         if (link1 == null) {
             LOG.error("MapUtils: No Link augmentation available. {}", link.getLinkId().getValue());
-            return null;
         }
         try {
             tempSpan = link1.getOMSAttributes().getSpan();
-            if (tempSpan == null) {
-                LOG.error("MapUtils: No Link getOMSAttributes available. {}", link.getLinkId().getValue());
-                return null;
-            }
-        } catch (NullPointerException e) {
+        }
+        catch (NullPointerException e) {
             LOG.error("MapUtils: No Link getOMSAttributes available. {}", link.getLinkId().getValue());
-            return null;
         }
+
         return tempSpan;
     }
 
+    public static LinkId extractOppositeLink(Link link) {
+        LinkId tmpoppositeLink = null;
+        org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1 linkOpposite
+            = link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class);
+        tmpoppositeLink = linkOpposite.getOppositeLink();
+        LOG.debug("PceLink: reading oppositeLink.  {}", linkOpposite.toString());
+        if (tmpoppositeLink == null) {
+            LOG.error("PceLink: Error reading oppositeLink. Link is ignored {}", link.getLinkId().getValue());
+            return null;
+        }
+        return tmpoppositeLink;
+    }
+
+
 }
index 80c1cc2d070551043fa742894ba94b4157649b01..7ce9b80d11f253c60b0990cf8c868c5d7a262be1 100644 (file)
@@ -5,25 +5,28 @@
  * 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.pce;
+
+package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import com.google.common.base.Optional;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
-import java.util.stream.Collectors;
 
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.transportpce.common.NetworkUtils;
 import org.opendaylight.transportpce.common.ResponseCodes;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
+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.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.Networks;
@@ -41,66 +44,78 @@ import org.slf4j.LoggerFactory;
 public class PceCalculation {
     /* Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
-    private DataBroker dataBroker = null;
+    private NetworkTransactionService networkTransactionService = null;
+
     ///////////// data parsed from Input/////////////////
     private PathComputationRequestInput input;
     private String anodeId = "";
     private String znodeId = "";
+
     private PceConstraints pceHardConstraints;
-    private PceConstraints pceSoftConstraints;
+//    private PceConstraints pceSoftConstraints;
+
     ///////////// Intermediate data/////////////////
     private List<PceLink> addLinks = new ArrayList<PceLink>();
     private List<PceLink> dropLinks = new ArrayList<PceLink>();
     private HashSet<NodeId> azSrgs = new HashSet<NodeId>();
+
     private PceNode aendPceNode = null;
     private PceNode zendPceNode = null;
+
     private List<Link> allLinks = null;
     private List<Node> allNodes = null;
+
     // this List serves graph calculation
     private Map<NodeId, PceNode> allPceNodes = new HashMap<NodeId, PceNode>();
     // this List serves calculation of ZtoA path descritopn
     // TODO maybe better solution is possible
     private Map<LinkId, PceLink> allPceLinks = new HashMap<LinkId, PceLink>();
+    private Set<LinkId> linksToExclude = new HashSet<LinkId>();
     private PceResult returnStructure;
 
-    public PceResult getReturnStructure() {
-        return this.returnStructure;
-    }
-
-    public enum NodeConstraint {
+    private enum ConstraintTypes {
         NONE, HARD_EXCLUDE, HARD_INCLUDE, HARD_DIVERSITY, SOFT_EXCLUDE, SOFT_INCLUDE, SOFT_DIVERSITY;
     }
 
-    public PceCalculation(PathComputationRequestInput input, DataBroker dataBroker, PceConstraints pceHardConstraints,
-            PceConstraints pceSoftConstraints, PceResult rc) {
+    public PceCalculation(PathComputationRequestInput input, NetworkTransactionService networkTransactionService,
+            PceConstraints pceHardConstraints, PceConstraints pceSoftConstraints, PceResult rc) {
         this.input = input;
-        this.dataBroker = dataBroker;
+        this.networkTransactionService = networkTransactionService;
         this.returnStructure = rc;
+
         this.pceHardConstraints = pceHardConstraints;
-        this.pceSoftConstraints = pceSoftConstraints;
+//        this.pceSoftConstraints = pceSoftConstraints;
         parseInput();
     }
 
-    // apply constraints to get applicable result
     public void calcPath() {
+
         LOG.info("In PceCalculation calcPath: ");
+
         if (!readMdSal()) {
-            this.returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
+            returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
             return;
         }
+
+        MapUtils.mapDiversityConstraints(allNodes, allLinks, pceHardConstraints);
+
         if (!analyzeNw()) {
-            this.returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
+            returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
             return;
         }
-        this.returnStructure.setRC(ResponseCodes.RESPONSE_OK);
+
+        printNodesInfo(allPceNodes);
+        // printLinksInfo(allPceLinks);
+
+        returnStructure.setRC(ResponseCodes.RESPONSE_OK);
         return;
     }
 
     private boolean parseInput() {
-        this.anodeId = this.input.getServiceAEnd().getNodeId();
-        this.znodeId = this.input.getServiceZEnd().getNodeId();
-        LOG.info("parseInput: A and Z :[{}] and [{}]", this.anodeId, this.znodeId);
-        this.returnStructure.setRate(this.input.getServiceAEnd().getServiceRate());
+        anodeId = input.getServiceAEnd().getNodeId();
+        znodeId = input.getServiceZEnd().getNodeId();
+        LOG.info("parseInput: A and Z :[{}] and [{}]", anodeId, znodeId);
+        returnStructure.setRate(input.getServiceAEnd().getServiceRate());
         return true;
     }
 
@@ -108,265 +123,319 @@ public class PceCalculation {
         LOG.info("readMdSal: network {}", NetworkUtils.OVERLAY_NETWORK_ID);
         InstanceIdentifier<Network> nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).build();
-        ReadOnlyTransaction readOnlyTransaction = this.dataBroker.newReadOnlyTransaction();
         Network nw = null;
         try {
             Optional<Network> nwOptional =
-                    readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier).get();
+                networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier).get();
             if (nwOptional.isPresent()) {
                 nw = nwOptional.get();
                 LOG.debug("readMdSal: network nodes: nwOptional.isPresent = true {}", nw.toString());
             }
-        } catch (ExecutionException | InterruptedException e) {
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("readMdSal: Error reading topology {}", nwInstanceIdentifier);
-            readOnlyTransaction.close();
-            this.returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
+            networkTransactionService.close();
+            returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
             throw new RuntimeException(
                     "readMdSal: Error reading from operational store, topology : " + nwInstanceIdentifier + " :" + e);
         }
-        readOnlyTransaction.close();
+        networkTransactionService.close();
+
         if (nw == null) {
             LOG.error("readMdSal: network is null: {}", nwInstanceIdentifier);
             return false;
         }
-        this.allNodes = nw.getNode().stream()
-                .sorted((node1, node2) -> node1.getNodeId().getValue().compareTo(node2.getNodeId().getValue()))
-                .collect(Collectors.toList());
+        allNodes = nw.getNode();
         Network1 nw1 = nw.augmentation(Network1.class);
-        this.allLinks = nw1.getLink();
-        if ((this.allNodes == null) || this.allNodes.isEmpty()) {
+
+        allLinks = nw1.getLink();
+        if (allNodes == null || allNodes.isEmpty()) {
             LOG.error("readMdSal: no nodes ");
             return false;
         }
-        LOG.info("readMdSal: network nodes: {} nodes added", this.allNodes.size());
-        if ((this.allLinks == null) || this.allLinks.isEmpty()) {
+        LOG.info("readMdSal: network nodes: {} nodes added", allNodes.size());
+        LOG.debug("readMdSal: network nodes: {} nodes added", allNodes.toString());
+
+        if (allLinks == null || allLinks.isEmpty()) {
             LOG.error("readMdSal: no links ");
             return false;
         }
-        LOG.info("readMdSal: network links: {} links added", this.allLinks.size());
+        LOG.info("readMdSal: network links: {} links added", allLinks.size());
+        LOG.debug("readMdSal: network links: {} links added", allLinks.toString());
+
         return true;
     }
 
     private boolean analyzeNw() {
-        LOG.debug("analyzeNw: allNodes size {}, allLinks size {}", this.allNodes.size(), this.allLinks.size());
-        for (Node node : this.allNodes) {
+
+        LOG.debug("analyzeNw: allNodes size {}, allLinks size {}", allNodes.size(), allLinks.size());
+
+        for (Node node : allNodes) {
             validateNode(node);
         }
-        LOG.debug("analyzeNw: allPceNodes size {} : {}", this.allPceNodes.size(), this.allPceNodes.toString());
-        if ((this.aendPceNode == null) || (this.zendPceNode == null)) {
+        LOG.debug("analyzeNw: allPceNodes size {}", allPceNodes.size());
+
+        if (aendPceNode == null || zendPceNode == null) {
             LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network");
             return false;
         }
-        for (Link link : this.allLinks) {
+
+        for (Link link : allLinks) {
             validateLink(link);
         }
-        LOG.debug("analyzeNw: AddLinks size {}, DropLinks size {}", this.addLinks.size(), this.dropLinks.size());
+
+        LOG.debug("analyzeNw: addLinks size {}, dropLinks size {}", addLinks.size(), dropLinks.size());
+
         // debug prints
-        LOG.info("analyzeNw: AZSrgs size = {}", this.azSrgs.size());
-        for (NodeId srg : this.azSrgs) {
-            LOG.info("analyzeNw: A/Z Srgs SRG = {}", srg.getValue());
+        LOG.debug("analyzeNw: azSrgs size = {}", azSrgs.size());
+        for (NodeId srg : azSrgs) {
+            LOG.debug("analyzeNw: A/Z Srgs SRG = {}", srg.getValue());
         }
         // debug prints
-        for (PceLink link : this.addLinks) {
-            filterAddLinks(link);
+
+        for (PceLink link : addLinks) {
+            filteraddLinks(link);
         }
-        for (PceLink link : this.dropLinks) {
-            filterDropLinks(link);
+        for (PceLink link : dropLinks) {
+            filterdropLinks(link);
+        }
+
+        LOG.info("analyzeNw: allPceNodes size {}, allPceLinks size {}", allPceNodes.size(), allPceLinks.size());
+
+        if ((allPceNodes.size() == 0) || (allPceLinks.size() == 0)) {
+            return false;
         }
-        LOG.info("analyzeNw: allPceNodes size {}, allPceLinks size {}", this.allPceNodes.size(), this.allPceLinks
-                .size());
+
+        LOG.debug("analyzeNw: allPceNodes {}", allPceNodes.toString());
+        LOG.debug("analyzeNw: allPceLinks {}", allPceLinks.toString());
+
         return true;
     }
 
-    private boolean filterAddLinks(PceLink pcelink) {
+    private boolean filteraddLinks(PceLink pcelink) {
+
         NodeId nodeId = pcelink.getSourceId();
-        if (this.azSrgs.contains(nodeId)) {
-            this.allPceLinks.put(pcelink.getLinkId(), pcelink);
-            this.allPceNodes.get(nodeId).addOutgoingLink(pcelink);
-            LOG.info("analyzeNw: Add_LINK added to source and to allPceLinks {}", pcelink.getLinkId().toString());
+
+        if (azSrgs.contains(nodeId)) {
+            allPceLinks.put(pcelink.getLinkId(), pcelink);
+            allPceNodes.get(nodeId).addOutgoingLink(pcelink);
+            LOG.debug("analyzeNw: Add_LINK added to source and to allPceLinks {}", pcelink.getLinkId().toString());
             return true;
         }
+
         // remove the SRG from PceNodes, as it is not directly connected to A/Z
-        this.allPceNodes.remove(nodeId);
+        allPceNodes.remove(nodeId);
         LOG.debug("analyzeNw: SRG removed {}", nodeId.getValue());
+
         return false;
     }
 
-    private boolean filterDropLinks(PceLink pcelink) {
+    private boolean filterdropLinks(PceLink pcelink) {
+
         NodeId nodeId = pcelink.getDestId();
-        if (this.azSrgs.contains(nodeId)) {
-            this.allPceLinks.put(pcelink.getLinkId(), pcelink);
-            this.allPceNodes.get(nodeId).addOutgoingLink(pcelink);
-            LOG.info("analyzeNw: Drop_LINK added to dest and to allPceLinks {}", pcelink.getLinkId().toString());
+
+        if (azSrgs.contains(nodeId)) {
+            allPceLinks.put(pcelink.getLinkId(), pcelink);
+            allPceNodes.get(nodeId).addOutgoingLink(pcelink);
+            LOG.debug("analyzeNw: Drop_LINK added to dest and to allPceLinks {}", pcelink.getLinkId().toString());
             return true;
         }
+
         // remove the SRG from PceNodes, as it is not directly connected to A/Z
-        this.allPceNodes.remove(pcelink.getDestId());
+        allPceNodes.remove(pcelink.getDestId());
         LOG.debug("analyzeNw: SRG removed {}", nodeId.getValue());
+
         return false;
     }
 
     private boolean validateLink(Link link) {
-        LOG.info("validateLink: link {} ", link.toString());
+
+        LOG.debug("validateLink: link {} ", link.toString());
+
+        if (linksToExclude.contains(link.getLinkId())) {
+            LOG.info("validateLink: Link is ignored due opposite link problem - {}", link.getLinkId().getValue());
+            return false;
+        }
+
         NodeId sourceId = link.getSource().getSourceNode();
         NodeId destId = link.getDestination().getDestNode();
-        PceNode source = this.allPceNodes.get(sourceId);
-        PceNode dest = this.allPceNodes.get(destId);
+        PceNode source = allPceNodes.get(sourceId);
+        PceNode dest = allPceNodes.get(destId);
+
         if (source == null) {
-            LOG.warn("validateLink: source node is rejected by node validation - {}", link.getSource().getSourceNode()
-                    .getValue());
+            LOG.debug("validateLink: Link is ignored due source node is rejected by node validation - {}",
+                    link.getSource().getSourceNode().getValue());
             return false;
         }
         if (dest == null) {
-            LOG.warn("validateLink: dest node is rejected by node validation - {}", link.getDestination().getDestNode()
-                    .getValue());
+            LOG.debug("validateLink: Link is ignored due dest node is rejected by node validation - {}",
+                    link.getDestination().getDestNode().getValue());
             return false;
         }
-        PceLink pcelink = new PceLink(link);
+
+        PceLink pcelink = new PceLink(link, source, dest);
         if (!pcelink.isValid()) {
-            LOG.error(" validateLink: Link is ignored due errors in network data ");
+            dropOppositeLink(link);
+            LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
             return false;
         }
+
         LinkId linkId = pcelink.getLinkId();
-        switch (pcelink.getLinkType()) {
+
+        switch (validateLinkConstraints(pcelink)) {
+            case HARD_EXCLUDE :
+                dropOppositeLink(link);
+                LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue());
+                return false;
+            default:
+                break;
+        }
+
+        switch (pcelink.getlinkType()) {
             case ROADMTOROADM :
-                this.allPceLinks.put(linkId, pcelink);
+                allPceLinks.put(linkId, pcelink);
                 source.addOutgoingLink(pcelink);
-                LOG.info("validateLink: ROADMTOROADM-LINK added to allPceLinks {}", pcelink.toString());
+                LOG.debug("validateLink: ROADMTOROADM-LINK added to allPceLinks {}", pcelink.toString());
                 break;
             case EXPRESSLINK :
-                this.allPceLinks.put(linkId, pcelink);
+                allPceLinks.put(linkId, pcelink);
                 source.addOutgoingLink(pcelink);
-                LOG.info("validateLink: EXPRESS-LINK added to allPceLinks {}", pcelink.toString());
+                LOG.debug("validateLink: EXPRESS-LINK added to allPceLinks {}", pcelink.toString());
                 break;
             case ADDLINK :
                 pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString(), true));
-                this.addLinks.add(pcelink);
-                LOG.info("validateLink: ADD-LINK saved  {}", pcelink.toString());
+                addLinks.add(pcelink);
+                LOG.debug("validateLink: ADD-LINK saved  {}", pcelink.toString());
                 break;
             case DROPLINK :
                 pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString(), false));
-                this.dropLinks.add(pcelink);
-                LOG.info("validateLink: DROP-LINK saved  {}", pcelink.toString());
+                dropLinks.add(pcelink);
+                LOG.debug("validateLink: DROP-LINK saved  {}", pcelink.toString());
                 break;
             case XPONDERINPUT :
-                this.azSrgs.add(sourceId);
-                // store separately all SRG links directly connected to A/Z
+                azSrgs.add(sourceId); // store separately all SRG links directly
+                // connected to A/Z
                 if (!dest.checkTP(pcelink.getDestTP().toString())) {
                     LOG.debug("validateLink: XPONDER-INPUT is rejected as NW port is busy - {} ", pcelink.toString());
                     return false;
                 }
-                pcelink.setClient(dest.getXpdrClient(pcelink.getDestTP().toString()));
-                this.allPceLinks.put(linkId, pcelink);
+                pcelink.setClient(dest.getClient(pcelink.getDestTP().toString()));
+                allPceLinks.put(linkId, pcelink);
                 source.addOutgoingLink(pcelink);
-                LOG.info("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink.toString());
+                LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink.toString());
                 break;
-            case XPONDEROUTPUT :
-                // does it mean XPONDER==>>SRG ?
-                this.azSrgs.add(destId);
-                // store separately all SRG links directly connected to A/Z
+            case XPONDEROUTPUT : // does it mean XPONDER==>>SRG ?
+                azSrgs.add(destId); // store separately all SRG links directly
+                // connected to A/Z
                 if (!source.checkTP(pcelink.getSourceTP().toString())) {
                     LOG.debug("validateLink: XPONDER-OUTPUT is rejected as NW port is busy - {} ", pcelink.toString());
                     return false;
                 }
-                pcelink.setClient(source.getXpdrClient(pcelink.getSourceTP().toString()));
-                this.allPceLinks.put(linkId, pcelink);
+                pcelink.setClient(source.getClient(pcelink.getSourceTP().toString()));
+                allPceLinks.put(linkId, pcelink);
                 source.addOutgoingLink(pcelink);
-                LOG.info("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink.toString());
+                LOG.debug("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink.toString());
                 break;
             default:
                 LOG.warn("validateLink: link type is not supported {}", pcelink.toString());
+
         }
+
         return true;
     }
 
     private boolean validateNode(Node node) {
-        String supNodeId = "";
-        OpenroadmNodeType nodeType = null;
-        NodeId nodeId = null;
-        if (node == null) {
-            LOG.error("validateNode: node is null, ignored ");
-            return false;
+        LOG.debug("validateNode: node {} ", node.toString());
+
+        // PceNode will be used in Graph algorithm
+        Node1 node1 = node.augmentation(Node1.class);
+        if (node1 == null) {
+            LOG.error("getNodeType: no Node1 (type) Augmentation for node: [{}]. Node is ignored", node.getNodeId());
         }
-        try {
-            // TODO: supporting IDs exist as a List. this code takes just the first element
-            nodeId = node.getNodeId();
-            supNodeId = node.getSupportingNode().get(0).getNodeRef().getValue();
-            if (supNodeId.equals("")) {
-                LOG.error("validateNode: Supporting node for node: [{}]. Node is ignored", nodeId.getValue());
-                return false;
-            }
-            // extract node type
-            Node1 node1 = node.augmentation(Node1.class);
-            if (node1 == null) {
-                LOG.error("validateNode: no Node1 (type) Augmentation for node: [{}]. Node is ignored", nodeId
-                        .getValue());
-                return false;
-            }
-            nodeType = node1.getNodeType();
-            /** Catch exception 'RuntimeException' is not allowed. [IllegalCatch]. */
-        } catch (NullPointerException e) {
-            LOG.error("validateNode: Error reading supporting node or node type for node '{}'", nodeId, e);
+        OpenroadmNodeType nodeType = node1.getNodeType();
+
+        PceNode pceNode = new PceNode(node,nodeType,node.getNodeId());
+        pceNode.validateAZxponder(anodeId, znodeId);
+        pceNode.initWLlist();
+
+        if (!pceNode.isValid()) {
+            LOG.warn(" validateNode: Node is ignored");
             return false;
         }
-        if (nodeType == OpenroadmNodeType.XPONDER) {
-            // Detect A and Z
-            if (supNodeId.equals(this.anodeId) || (supNodeId.equals(this.znodeId))) {
-                LOG.info("validateNode: A or Z node detected == {}", node.getNodeId().getValue());
-            } else {
-                LOG.warn("validateNode: XPONDER is ignored == {}", node.getNodeId().getValue());
-                return false;
-            }
-        }
-        switch (validateNodeConstraints(nodeId.getValue(), supNodeId)) {
+
+        switch (validateNodeConstraints(pceNode)) {
             case HARD_EXCLUDE :
-                LOG.info("validateNode: constraints : node is ignored == {}", nodeId.getValue());
                 return false;
-            default:
+
+            default :
                 break;
         }
-        PceNode pceNode = new PceNode(node, nodeType, nodeId);
-        if (!pceNode.isValid()) {
-            LOG.error(" validateNode: Node is ignored due errors in network data ");
-            return false;
-        }
-        if (supNodeId.equals(this.anodeId)) {
-            if (this.aendPceNode == null) {
-                if (endPceNode(nodeType, nodeId, pceNode, true)) {
-                    if (!pceNode.isValid()) {
-                        LOG.error("validateNode: There are no available wavelengths in node {}", nodeId.getValue());
-                        return false;
-                    }
-                    this.aendPceNode = pceNode;
-                }
-            } else {
-                LOG.warn("aendPceNode already gets: {}", this.aendPceNode);
+
+        if (pceNode.getSupNodeIdPceNode().equals(anodeId)) {
+            if (endPceNode(nodeType,pceNode.getNodeId(), pceNode)) {
+                this.aendPceNode = pceNode;
             }
         }
-        if (supNodeId.equals(this.znodeId)) {
-            if (this.zendPceNode == null) {
-                if (endPceNode(nodeType, nodeId, pceNode, false)) {
-                    if (!pceNode.isValid()) {
-                        LOG.error("validateNode: There are no available wavelengths in node {}", nodeId.getValue());
-                        return false;
-                    }
-                    this.zendPceNode = pceNode;
-                }
-            } else {
-                LOG.warn("zendPceNode already gets: {}", this.zendPceNode);
+        if (pceNode.getSupNodeIdPceNode().equals(znodeId)) {
+            if (endPceNode(nodeType,pceNode.getNodeId(), pceNode)) {
+                this.zendPceNode = pceNode;
             }
         }
-        pceNode.initWLlist();
-        if (!pceNode.isValid()) {
-            LOG.error("validateNode: There are no available wavelengths in node {}", nodeId.getValue());
-            return false;
-        }
-        this.allPceNodes.put(nodeId, pceNode);
-        LOG.debug("validateNode: node is saved {}", nodeId.getValue());
+
+        allPceNodes.put(pceNode.getNodeId(), pceNode);
+        LOG.debug("validateNode: node is saved {}", pceNode.getNodeId().getValue());
         return true;
     }
 
-    private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceNode pceNode, Boolean aend) {
+    private ConstraintTypes validateNodeConstraints(PceNode pcenode) {
+
+        if (pceHardConstraints.getExcludeSupNodes().isEmpty()  && pceHardConstraints.getExcludeCLLI().isEmpty()) {
+            return ConstraintTypes.NONE;
+        }
+
+        if (pceHardConstraints.getExcludeSupNodes().contains(pcenode.getSupNodeIdPceNode())) {
+            LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
+            return ConstraintTypes.HARD_EXCLUDE;
+        }
+        if (pceHardConstraints.getExcludeCLLI().contains(pcenode.getCLLI())) {
+            LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
+            return ConstraintTypes.HARD_EXCLUDE;
+        }
+
+        return ConstraintTypes.NONE;
+    }
+
+    private ConstraintTypes validateLinkConstraints(PceLink link) {
+        if (pceHardConstraints.getExcludeSRLG().isEmpty()) {
+            return ConstraintTypes.NONE;
+        }
+
+        // for now SRLG is the only constraint for link
+        if (link.getlinkType() != OpenroadmLinkType.ROADMTOROADM) {
+            return ConstraintTypes.NONE;
+        }
+
+        List<Long> constraints = new ArrayList<Long>(pceHardConstraints.getExcludeSRLG());
+        constraints.retainAll(link.getsrlgList());
+        if (!constraints.isEmpty()) {
+            LOG.info("validateLinkConstraints: {}", link.getLinkId().getValue());
+            return ConstraintTypes.HARD_EXCLUDE;
+        }
+
+        return ConstraintTypes.NONE;
+    }
+
+    private void dropOppositeLink(Link link) {
+        LinkId opplink = MapUtils.extractOppositeLink(link);
+
+        PceLink oppPceLink = allPceLinks.get(opplink);
+        if (oppPceLink != null) {
+            allPceLinks.remove(oppPceLink);
+        } else {
+            linksToExclude.add(opplink);
+        }
+    }
+
+    private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceNode pceNode) {
         Boolean add = true;
         switch (openroadmNodeType) {
             case SRG :
@@ -384,28 +453,12 @@ public class PceCalculation {
         return add;
     }
 
-    private NodeConstraint validateNodeConstraints(String nodeId, String supNodeId) {
-        if (this.pceHardConstraints.getExcludeNodes().contains(nodeId)) {
-            return NodeConstraint.HARD_EXCLUDE;
-        }
-        if (this.pceHardConstraints.getExcludeNodes().contains(supNodeId)) {
-            return NodeConstraint.HARD_EXCLUDE;
-        }
-        if (this.pceHardConstraints.getIncludeNodes().contains(nodeId)) {
-            return NodeConstraint.HARD_INCLUDE;
-        }
-        if (this.pceHardConstraints.getIncludeNodes().contains(supNodeId)) {
-            return NodeConstraint.HARD_INCLUDE;
-        }
-        return NodeConstraint.NONE;
-    }
-
-    public PceNode getaPceNode() {
-        return this.aendPceNode;
+    public PceNode getaendPceNode() {
+        return aendPceNode;
     }
 
-    public PceNode getzPceNode() {
-        return this.zendPceNode;
+    public PceNode getzendPceNode() {
+        return zendPceNode;
     }
 
     public Map<NodeId, PceNode> getAllPceNodes() {
@@ -415,4 +468,25 @@ public class PceCalculation {
     public Map<LinkId, PceLink> getAllPceLinks() {
         return this.allPceLinks;
     }
+
+    public PceResult getReturnStructure() {
+        return returnStructure;
+    }
+
+    private static void printNodesInfo(Map<NodeId, PceNode> allpcenodes) {
+        Iterator<Map.Entry<NodeId, PceNode>> nodes = allpcenodes.entrySet().iterator();
+        while (nodes.hasNext()) {
+            PceNode pcenode = nodes.next().getValue();
+            List<PceLink> links = pcenode.getOutgoingLinks();
+            LOG.info("In printNodes in node {} : outgoing links {} ", pcenode.getNodeId().getValue(), links.toString());
+        }
+    }
+
+    private static void printLinksInfo(Map<LinkId, PceLink> allpcelinks) {
+        Iterator<Map.Entry<LinkId, PceLink>> links = allpcelinks.entrySet().iterator();
+        while (links.hasNext()) {
+            LOG.info("In printLinksInfo link {} : ", links.next().getValue().toString());
+        }
+    }
+
 }
similarity index 61%
rename from pce/src/main/java/org/opendaylight/transportpce/pce/PceLink.java
rename to pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java
index 6320d9e5304bc214021efa5636c1b8bef331c468..72adcb7f94274a87faac613887f38afeda190bdf 100644 (file)
@@ -6,11 +6,12 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.transportpce.pce;
+package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import java.util.List;
 
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.link.oms.attributes.Span;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
@@ -23,7 +24,7 @@ import org.slf4j.LoggerFactory;
 public class PceLink {
 
     /* Logging. */
-    private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
+    private static final Logger LOG = LoggerFactory.getLogger(PceLink.class);
 
     ///////////////////////// LINKS ////////////////////
     /*
@@ -35,7 +36,7 @@ public class PceLink {
     private boolean isValid = true;
 
     // this member is for XPONDER INPUT/OUTPUT links.
-    // it keeps name of client corresponding to NETWORK TP
+    // it keeps name of client correcponding to NETWORK TP
     private String client = "";
 
     private final LinkId linkId;
@@ -44,13 +45,17 @@ public class PceLink {
     private final NodeId destId;
     private final Object sourceTP;
     private final Object destTP;
+    private final String sourceSupNodeId;
+    private final String destSupNodeId;
+    private final String sourceCLLI;
+    private final String destCLLI;
     private final LinkId oppositeLink;
     private final Long latency;
-    private final List<Long> srlg;
+    private final List<Long> srlgList;
     private final double osnr;
     private final Span omsAttributesSpan;
 
-    public PceLink(Link link) {
+    public PceLink(Link link, PceNode source, PceNode dest) {
         LOG.debug("PceLink: : PceLink start ");
 
         this.linkId = link.getLinkId();
@@ -61,27 +66,34 @@ public class PceLink {
         this.sourceTP = link.getSource().getSourceTp();
         this.destTP = link.getDestination().getDestTp();
 
-        this.linkType = calcType(link);
+        this.sourceSupNodeId = source.getSupNodeIdPceNode();
+        this.destSupNodeId = dest.getSupNodeIdPceNode();
+
+        this.sourceCLLI = source.getCLLI();
+        this.destCLLI = dest.getCLLI();
+
+        this.linkType = MapUtils.calcType(link);
 
         this.oppositeLink = calcOpposite(link);
         this.latency = calcLatency(link);
 
         if (this.linkType == OpenroadmLinkType.ROADMTOROADM) {
             this.omsAttributesSpan = MapUtils.getOmsAttributesSpan(link);
-            this.srlg = MapUtils.getSRLG(link);
+            this.srlgList = MapUtils.getSRLG(link);
             this.osnr = retrieveOSNR();
         } else {
             this.omsAttributesSpan = null;
-            this.srlg = null;
-            this.osnr = 0L;
+            this.srlgList = null;
+            this.osnr = 0.0;
         }
 
+
         LOG.debug("PceLink: created PceLink  {}", toString());
     }
 
     private OpenroadmLinkType calcType(Link link) {
         org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.@Nullable Link1 link1 = null;
-        OpenroadmLinkType tmplType = null;
+        OpenroadmLinkType tmplinkType = null;
 
         // ID and type
         link1 = link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130
@@ -92,44 +104,37 @@ public class PceLink {
             return null;
         }
 
-        tmplType = link1.getLinkType();
-        if (tmplType == null) {
+        tmplinkType = link1.getLinkType();
+        if (tmplinkType == null) {
             this.isValid = false;
             LOG.error("PceLink: No Link type available. Link is ignored {}", this.linkId);
             return null;
         }
-        return tmplType;
+        return tmplinkType;
     }
 
     private LinkId calcOpposite(Link link) {
         // opposite link
-        LinkId tmpoppositeLink = null;
-        Link1 linkOpposite = link.augmentation(Link1.class);
-        if (linkOpposite.getOppositeLink() != null) {
-            tmpoppositeLink = linkOpposite.getOppositeLink();
-        } else {
-            LOG.error("link {} has no opposite link", link.getLinkId().getValue());
-        }
-        LOG.debug("PceLink: reading oppositeLink.  {}", linkOpposite.toString());
+
+        LinkId tmpoppositeLink = MapUtils.extractOppositeLink(link);
         if (tmpoppositeLink == null) {
-            this.isValid = false;
-            LOG.error("PceLink: Error reading oppositeLink. Link is ignored {}", this.linkId);
-            return null;
+            LOG.error("PceLink: Error calcOpposite. Link is ignored {}", link.getLinkId().getValue());
+            isValid = false;
         }
         return tmpoppositeLink;
     }
 
     private Long calcLatency(Link link) {
-        Long tmplatency = (long)0;
+        Long tmplatency = 1L;
         Link1 link1 = null;
         // latency
         link1 = link.augmentation(Link1.class);
-        tmplatency = link1.getLinkLatency();
-        if (tmplatency == null) {
-            tmplatency = (long) 0;
+        try {
+            tmplatency = link1.getLinkLatency();
+        } catch (NullPointerException e) {
+            LOG.debug("the latency does not exist for this link");
         }
         return tmplatency;
-
     }
 
     @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance")
@@ -154,8 +159,8 @@ public class PceLink {
         double constantB = 0.72782;
         double constantC = -0.532331;
         double constactD = -0.019549;
-        double upperBoundOSNR = 33;
-        double lowerBoundOSNR = 0.1;
+        double upperBoundosnr = 33;
+        double lowerBoundosnr = 0.1;
 
         if (omsAttributesSpan ==  null) {
             // indicates no data or N/A
@@ -200,49 +205,49 @@ public class PceLink {
                 break;
         }
         spanOsnrDb = constantA + constantB * power + constantC * loss + constactD * power * loss;
-        if (spanOsnrDb > upperBoundOSNR) {
-            spanOsnrDb =  upperBoundOSNR;
-        } else if (spanOsnrDb < lowerBoundOSNR) {
-            spanOsnrDb = lowerBoundOSNR;
+        if (spanOsnrDb > upperBoundosnr) {
+            spanOsnrDb =  upperBoundosnr;
+        } else if (spanOsnrDb < lowerBoundosnr) {
+            spanOsnrDb = lowerBoundosnr;
         }
         spanOsnrLu = Math.pow(10, (spanOsnrDb / 10.0));
         sum = PceConstraints.CONST_OSNR / spanOsnrLu;
         linkOsnrLu = sum;
-        LOG.debug("In retrieveOSNR: link OSNR is {} dB", linkOsnrLu);
+        //link_osnr_dB = 10 * Math.log10(1 / sum);
+        LOG.debug("In retrieveosnr: link osnr is {} dB", linkOsnrLu);
         return linkOsnrLu;
     }
 
-
     public LinkId getOppositeLink() {
-        return this.oppositeLink;
+        return oppositeLink;
     }
 
     public Object getSourceTP() {
-        return this.sourceTP;
+        return sourceTP;
     }
 
     public Object getDestTP() {
-        return this.destTP;
+        return destTP;
     }
 
-    public OpenroadmLinkType getLinkType() {
-        return this.linkType;
+    public OpenroadmLinkType getlinkType() {
+        return linkType;
     }
 
     public LinkId getLinkId() {
-        return this.linkId;
+        return linkId;
     }
 
     public NodeId getSourceId() {
-        return this.sourceId;
+        return sourceId;
     }
 
     public NodeId getDestId() {
-        return this.destId;
+        return destId;
     }
 
     public String getClient() {
-        return this.client;
+        return client;
     }
 
     public void setClient(String client) {
@@ -251,25 +256,66 @@ public class PceLink {
 
     // Double for transformer of JUNG graph
     public Double getLatency() {
-        return this.latency.doubleValue();
+        return latency.doubleValue();
+    }
+
+    public String getsourceSupNodeId() {
+        return sourceSupNodeId;
+    }
+
+    public String getdestSupNodeId() {
+        return destSupNodeId;
+    }
+
+    public List<Long> getsrlgList() {
+        return srlgList;
+    }
+
+    public double getosnr() {
+        return osnr;
+    }
+
+    public String getsourceCLLI() {
+        return sourceCLLI;
+    }
+
+    public String getdestCLLI() {
+        return destCLLI;
     }
 
     public boolean isValid() {
-        if ((this.linkId == null) || (this.linkType == null) || (this.oppositeLink == null)) {
-            this.isValid = false;
-            LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", this.linkId);
+        if ((this.linkId == null) || (this.linkType == null)
+                || (this.oppositeLink == null)) {
+            isValid = false;
+            LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", linkId);
         }
-        if ((this.sourceId == null) || (this.destId == null) || (this.sourceTP == null) || (this.destTP == null)) {
-            this.isValid = false;
-            LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", this.linkId);
+        if ((this.sourceId == null) || (this.destId == null)
+                || (this.sourceTP == null) || (this.destTP == null)) {
+            isValid = false;
+            LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", linkId);
         }
-
-        return this.isValid;
+        if ((this.sourceSupNodeId.equals("")) || (this.destSupNodeId.equals(""))) {
+            isValid = false;
+            LOG.error("PceLink: No Link source SuppNodeID or destination SuppNodeID is available. Link is ignored {}",
+                linkId);
+        }
+        if ((this.sourceCLLI.equals("")) || (this.destCLLI.equals(""))) {
+            isValid = false;
+            LOG.error("PceLink: No Link source CLLI or destination CLLI is available. Link is ignored {}", linkId);
+        }
+        if ((this.omsAttributesSpan == null) && (this.linkType == OpenroadmLinkType.ROADMTOROADM)) {
+            isValid = false;
+            LOG.error("PceLink: Error reading Span for OMS link. Link is ignored {}", linkId);
+        }
+        if ((this.srlgList != null) && (this.srlgList.isEmpty())) {
+            isValid = false;
+            LOG.error("PceLink: Empty srlgList for OMS link. Link is ignored {}", linkId);
+        }
+        return isValid;
     }
 
-    @Override
     public String toString() {
-        return "PceLink type=" + this.linkType + " ID=" + this.linkId.toString() + " latecy=" + this.latency;
+        return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latecy=" + latency;
     }
 
 }
similarity index 82%
rename from pce/src/main/java/org/opendaylight/transportpce/pce/PceNode.java
rename to pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceNode.java
index 57797640ea7e1bfe5bf26e0dc69a61afa79acf3c..2fcc5df57a014750d42dc0816f2a13cbe031d2d3 100644 (file)
@@ -5,7 +5,8 @@
  * 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.pce;
+
+package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -14,6 +15,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.TreeMap;
 
+import org.opendaylight.transportpce.pce.SortPortsByName;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.pp.attributes.UsedWavelength;
@@ -30,10 +32,15 @@ public class PceNode {
     ////////////////////////// NODES ///////////////////////////
     /*
      */
+
     private boolean valid = true;
+
     private final Node node;
     private final NodeId nodeId;
     private final OpenroadmNodeType nodeType;
+    private final String supNodeId;
+    private final String clli;
+
     // wavelength calculation per node type
     private List<Long> availableWLindex = new ArrayList<Long>();
     private Map<String, OpenroadmTpType> availableSrgPp = new TreeMap<String, OpenroadmTpType>();
@@ -46,6 +53,9 @@ public class PceNode {
         this.node = node;
         this.nodeId = nodeId;
         this.nodeType = nodeType;
+        this.supNodeId = getSupNodeId(node);
+        this.clli = MapUtils.getCLLI(node);
+
         if ((node == null) || (nodeId == null) || (nodeType == null)) {
             LOG.error("PceNode: one of parameters is not populated : nodeId, node type");
             this.valid = false;
@@ -116,6 +126,26 @@ public class PceNode {
         return;
     }
 
+
+
+/*    public PceNode(Node node, OpenroadmNodeType nodeType, NodeId nodeId,
+            String supNodeId, String clli) {
+        this.node = node;
+        this.nodeId = nodeId;
+        this.nodeType = nodeType;
+        this.supNodeId = supNodeId;
+        this.clli = clli;
+
+        if ((node == null) || (nodeId == null) || (nodeType == null)
+                || (supNodeId == null) || (clli == null)) {
+            LOG.error(
+                    "PceNode: one of parameters is not populated : nodeId, node type, supporting nodeId");
+            valid = false;
+        }
+
+        LOG.debug(" PceNode built :{}", this.toString());
+    }
+*/
     public void initWLlist() {
         this.availableWLindex.clear();
         if (!isValid()) {
@@ -256,6 +286,42 @@ public class PceNode {
         }
     }
 
+    private String getSupNodeId(Node inputNode) {
+        String tempSupId = "";
+        // TODO: supporting IDs exist as a List. this code takes just the
+        // first element
+        tempSupId = MapUtils.getSupNode(inputNode);
+        if (tempSupId.equals("")) {
+            LOG.error("getSupNodeId: Empty Supporting node for node: [{}]. Node is ignored", inputNode.getNodeId());
+        }
+        return tempSupId;
+    }
+
+    public void validateAZxponder(String anodeId, String znodeId) {
+        if (!isValid()) {
+            return;
+        }
+
+        if (this.nodeType != OpenroadmNodeType.XPONDER) {
+            return;
+        }
+
+        // Detect A and Z
+        if (this.supNodeId.equals(anodeId) || (this.supNodeId.equals(znodeId))) {
+
+            LOG.info("validateAZxponder: A or Z node detected == {}", nodeId.getValue());
+            initXndrTps();
+            return;
+        }
+
+        LOG.debug("validateAZxponder: XPONDER is ignored == {}", nodeId.getValue());
+        valid = false;
+    }
+
+    public String getXpdrClient(String tp) {
+        return this.clientPerNwTp.get(tp);
+    }
+
     public boolean checkTP(String tp) {
         return !(this.usedXpndrNWTps.contains(tp));
     }
@@ -265,11 +331,15 @@ public class PceNode {
     }
 
     public boolean isValid() {
-        return this.valid;
+        if ((node == null) || (nodeId == null) || (nodeType == null) || (supNodeId == null) || (clli == null)) {
+            LOG.error("PceNode: one of parameters is not populated : nodeId, node type, supporting nodeId");
+            valid = false;
+        }
+        return valid;
     }
 
     public List<Long> getAvailableWLs() {
-        return this.availableWLindex;
+        return availableWLindex;
     }
 
     public void addOutgoingLink(PceLink outLink) {
@@ -277,15 +347,31 @@ public class PceNode {
     }
 
     public List<PceLink> getOutgoingLinks() {
-        return this.outgoingLinks;
+        return outgoingLinks;
     }
 
-    public String getXpdrClient(String tp) {
-        return this.clientPerNwTp.get(tp);
+    public String getClient(String tp) {
+        return clientPerNwTp.get(tp);
+    }
+
+    public NodeId getNodeId() {
+        return nodeId;
+    }
+
+    public String getSupNodeIdPceNode() {
+        return supNodeId;
+    }
+
+    public String getCLLI() {
+        return clli;
     }
 
-    @Override
     public String toString() {
-        return "PceNode type=" + this.nodeType + " ID=" + this.nodeId.getValue();
+        return "PceNode type=" + nodeType + " ID=" + nodeId.getValue() + " CLLI=" + clli;
     }
+
+    public void printLinksOfNode() {
+        LOG.info(" outgoing links of node {} : {} ", nodeId.getValue(), this.getOutgoingLinks().toString());
+    }
+
 }
similarity index 66%
rename from pce/src/main/java/org/opendaylight/transportpce/pce/PceResult.java
rename to pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceResult.java
index b7119d898968455bd1c213fcf04e741939ba6c4b..233d785d86222f79357bb1338b10b418fb229fef 100644 (file)
@@ -6,16 +6,16 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.transportpce.pce;
+package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import org.opendaylight.transportpce.common.ResponseCodes;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirection;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ZToADirection;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class PceResult {
-    /* Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(PceResult.class);
     private String calcMessage = "503 Calculator Unavailable";
     private boolean calcStatus = false;
@@ -38,41 +38,41 @@ public class PceResult {
 
     public void setRC(String rc) {
         switch (rc) {
-            case ResponseCodes.RESPONSE_OK:
-                this.calcMessage = "Path is calculated";
-                this.calcStatus = true;
-                this.responseCode = ResponseCodes.RESPONSE_OK;
+            case ResponseCodes.RESPONSE_OK :
+                calcMessage = "Path is calculated";
+                calcStatus = true;
+                responseCode = ResponseCodes.RESPONSE_OK;
                 break;
-            case ResponseCodes.RESPONSE_FAILED:
-                this.responseCode = ResponseCodes.RESPONSE_FAILED;
-                this.calcStatus = false;
-                this.calcMessage = "No path available";
+            case ResponseCodes.RESPONSE_FAILED :
+                responseCode = ResponseCodes.RESPONSE_FAILED;
+                calcStatus = false;
+                calcMessage = "No path available";
                 break;
             default:
                 LOG.error("setRC: RespondeCodes unknown");
         }
     }
 
-    @Override
     public String toString() {
-        return ("[" + this.calcMessage + "] code:[" + this.responseCode + "] wavelength=" + this.resultWavelength
-                + " localCause=" + this.localCause + " rate=" + this.rate);
+        return ("[" + calcMessage + "] code:[" + responseCode + "] wavelength="
+                + resultWavelength + " localCause=" + localCause + " rate="
+                + rate);
     }
 
     public boolean getStatus() {
-        return this.calcStatus;
+        return calcStatus;
     }
 
     public String getMessage() {
-        return this.calcMessage;
+        return calcMessage;
     }
 
     public String getResponseCode() {
-        return this.responseCode;
+        return responseCode;
     }
 
     public long getResultWavelength() {
-        return this.resultWavelength;
+        return resultWavelength;
     }
 
     public void setResultWavelength(long resultWavelength) {
@@ -80,23 +80,23 @@ public class PceResult {
     }
 
     public AToZDirection getAtoZDirection() {
-        return this.atozdirection;
+        return atozdirection;
     }
 
     public ZToADirection getZtoADirection() {
-        return this.ztoadirection;
+        return ztoadirection;
     }
 
-    public void setAtoZDirection(AToZDirection atozdirectionIn) {
-        this.atozdirection = atozdirectionIn;
+    public void setAtoZDirection(AToZDirection atozDirection) {
+        this.atozdirection = atozDirection;
     }
 
-    public void setZtoADirection(ZToADirection ztoadirectionIn) {
-        this.ztoadirection = ztoadirectionIn;
+    public void setZtoADirection(ZToADirection ztoaDirection) {
+        this.ztoadirection = ztoaDirection;
     }
 
     public long getRate() {
-        return this.rate;
+        return rate;
     }
 
     public void setRate(long rate) {
@@ -104,21 +104,20 @@ public class PceResult {
     }
 
     public LocalCause getLocalCause() {
-        return this.localCause;
+        return localCause;
     }
 
     public void setLocalCause(LocalCause lc) {
         // For now keep the very first fatal problem
-        // TODO. Later this value might become history of algo if all significant problems are added here as to List
-        if (this.localCause == LocalCause.NONE) {
+        // TODO. Later this value might become history of algo if all
+        // significant problems are added here as to List
+        if (localCause == LocalCause.NONE) {
             this.localCause = lc;
         }
     }
 
-
     public void setCalcMessage(String calcMessage) {
         this.calcMessage = calcMessage;
     }
 
-
 }
index dd4ec8a284c1aa9c4e04b6e54d4f7690de8dc1a9..48a19ef4674b76677c703c08610e9d7c36506d7d 100644 (file)
@@ -16,8 +16,8 @@ import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.transportpce.pce.PceComplianceCheck;
 import org.opendaylight.transportpce.pce.PceComplianceCheckResult;
 import org.opendaylight.transportpce.pce.PceSendingPceRPCs;
@@ -57,13 +57,14 @@ public class PathComputationServiceImpl implements PathComputationService {
 
     private static final Logger LOG = LoggerFactory.getLogger(PathComputationServiceImpl.class);
     private final NotificationPublishService notificationPublishService;
-    private final DataBroker dataBroker;
+    private NetworkTransactionService networkTransactionService;
     private final ListeningExecutorService executor;
     ServicePathRpcResult notification = null;
 
-    public PathComputationServiceImpl(DataBroker dataBroker, NotificationPublishService notificationPublishService) {
+    public PathComputationServiceImpl(NetworkTransactionService networkTransactionService,
+                                      NotificationPublishService notificationPublishService) {
         this.notificationPublishService = notificationPublishService;
-        this.dataBroker = dataBroker;
+        this.networkTransactionService = networkTransactionService;
         this.executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
     }
 
@@ -149,7 +150,7 @@ public class PathComputationServiceImpl implements PathComputationService {
                         RpcStatusEx.Pending, "Service compliant, submitting pathComputation Request ...", null);
                 String message = "";
                 String responseCode = "";
-                PceSendingPceRPCs sendingPCE = new PceSendingPceRPCs(input, dataBroker);
+                PceSendingPceRPCs sendingPCE = new PceSendingPceRPCs(input, networkTransactionService);
                 sendingPCE.pathComputation();
                 message = sendingPCE.getMessage();
                 responseCode = sendingPCE.getResponseCode();
@@ -185,7 +186,7 @@ public class PathComputationServiceImpl implements PathComputationService {
                 output.setConfigurationResponseCommon(configurationResponseCommon.build())
                         .setResponseParameters(rpb.build());
 
-                //add the GNPy result
+              //add the GNPy result
                 GnpyResult gnpyAtoZ = sendingPCE.getGnpy_AtoZ();
                 GnpyResult gnpyZtoA = sendingPCE.getGnpy_ZtoA();
                 List<GnpyResponse> listResponse = new ArrayList<>();
@@ -256,4 +257,5 @@ public class PathComputationServiceImpl implements PathComputationService {
                 .setFeasibility(feasible).build();
         return gnpypResp;
     }
-}
+
+}
\ No newline at end of file
index 6b0dbb68cbcc09e1f2af3762ef082ad6c6211e77..7560106a0626e4742ddd9aee08e71f4999b0fbfa 100755 (executable)
@@ -13,6 +13,8 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
   xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
   odl:use-default-for-reference-types="true">
 
+  <reference id="networkTransactionImpl" interface="org.opendaylight.transportpce.common.network.NetworkTransactionService" />
+
   <reference id="dataBroker"
         interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
         odl:type="default"/>
@@ -27,7 +29,7 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
   <bean id="pceServiceImpl"
         class="org.opendaylight.transportpce.pce.service.PathComputationServiceImpl"
         init-method="init" destroy-method="close">
-    <argument ref="dataBroker"/>
+    <argument ref="networkTransactionImpl"/>
     <argument ref="notificationPublishService" />
   </bean>
 
index 8457c2e6b1aff594ff0ac55724d5a4dd79f2bd01..62185064fe47decbeef8f2a1e21d51115b65a0ee 100644 (file)
         <source><source-node>OpenROADM-1-4-SRG1</source-node><source-tp>SRG1-PP4-TX</source-tp></source>        <destination><dest-node>XPONDER-1-4</dest-node><dest-tp>XPDR-NW4-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-1-4XPDR-NW4-TX-toOpenROADM-1-4-SRG1-SRG1-PP4-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-1-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber1</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-1-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber2</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2</opposite-link>
+    <source><source-node>OpenROADM-1-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber56</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1</opposite-link>
+    <source><source-node>OpenROADM-1-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber3</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1</opposite-link>
+    <source><source-node>OpenROADM-1-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2</opposite-link>
+    <source><source-node>OpenROADM-1-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber4</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-1-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber57</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-1-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber5</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-2-1-DEG1-DEG1-CTP-TXtoOpenROADM-2-1-DEG2-DEG2-CTP-RX</link-id>
         <source><source-node>OpenROADM-2-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-2-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG2-DEG2-CTP-TXtoOpenROADM-2-1-DEG1-DEG1-CTP-RX</opposite-link>
         <source><source-node>OpenROADM-2-4-SRG1</source-node><source-tp>SRG1-PP4-TX</source-tp></source>        <destination><dest-node>XPONDER-2-4</dest-node><dest-tp>XPDR-NW4-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-2-4XPDR-NW4-TX-toOpenROADM-2-4-SRG1-SRG1-PP4-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-2-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber6</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-2-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber7</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2</opposite-link>
+    <source><source-node>OpenROADM-2-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber8</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1</opposite-link>
+    <source><source-node>OpenROADM-2-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber9</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1</opposite-link>
+    <source><source-node>OpenROADM-2-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber10</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2</opposite-link>
+    <source><source-node>OpenROADM-2-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber11</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-2-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber58</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-    <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG2-DEG2-CTP-RX</link-id>
-        <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-3-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
+    <source><source-node>OpenROADM-2-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber12</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+    <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+        <link-id>OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG2-DEG2-CTP-RX</link-id>
+        <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>
+        <destination><dest-node>OpenROADM-3-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG2-DEG2-CTP-TXtoOpenROADM-3-1-DEG1-DEG1-CTP-RX</opposite-link>
-        <link-type xmlns="http://org/openroadm/network/topology">EXPRESS-LINK</link-type></link>
-    <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG3-DEG3-CTP-RX</link-id>
+        <link-type xmlns="http://org/openroadm/network/topology">EXPRESS-LINK</link-type>
+    </link>
+    <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+        <link-id>OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG3-DEG3-CTP-RX</link-id>
         <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-3-1-DEG3</dest-node><dest-tp>DEG3-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG3-DEG3-CTP-TXtoOpenROADM-3-1-DEG1-DEG1-CTP-RX</opposite-link>
         <link-type xmlns="http://org/openroadm/network/topology">EXPRESS-LINK</link-type></link>
         <source><source-node>OpenROADM-3-4-SRG1</source-node><source-tp>SRG1-PP4-TX</source-tp></source>        <destination><dest-node>XPONDER-3-4</dest-node><dest-tp>XPDR-NW4-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-3-4XPDR-NW4-TX-toOpenROADM-3-4-SRG1-SRG1-PP4-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber13</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-3-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber14</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2</opposite-link>
+    <source><source-node>OpenROADM-3-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber15</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1</opposite-link>
+    <source><source-node>OpenROADM-3-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber16</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1</opposite-link>
+    <source><source-node>OpenROADM-3-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber17</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2</opposite-link>
+    <source><source-node>OpenROADM-3-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber18</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-3-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber19</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-3-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber20</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-4-1-DEG1-DEG1-CTP-TXtoOpenROADM-4-1-DEG2-DEG2-CTP-RX</link-id>
         <source><source-node>OpenROADM-4-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-4-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG2-DEG2-CTP-TXtoOpenROADM-4-1-DEG1-DEG1-CTP-RX</opposite-link>
         <source><source-node>OpenROADM-4-4-SRG1</source-node><source-tp>SRG1-PP4-TX</source-tp></source>        <destination><dest-node>XPONDER-4-4</dest-node><dest-tp>XPDR-NW4-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-4-4XPDR-NW4-TX-toOpenROADM-4-4-SRG1-SRG1-PP4-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-4-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber21</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-4-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber22</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2</opposite-link>
+    <source><source-node>OpenROADM-4-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber23</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1</opposite-link>
+    <source><source-node>OpenROADM-4-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber24</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1</opposite-link>
+    <source><source-node>OpenROADM-4-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber25</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2</opposite-link>
+    <source><source-node>OpenROADM-4-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber26</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-4-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber27</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-4-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber28</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-5-1-DEG1-DEG1-CTP-TXtoOpenROADM-5-1-DEG2-DEG2-CTP-RX</link-id>
         <source><source-node>OpenROADM-5-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-5-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG2-DEG2-CTP-TXtoOpenROADM-5-1-DEG1-DEG1-CTP-RX</opposite-link>
         <source><source-node>OpenROADM-5-4-SRG1</source-node><source-tp>SRG1-PP4-TX</source-tp></source>        <destination><dest-node>XPONDER-5-4</dest-node><dest-tp>XPDR-NW4-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-5-4XPDR-NW4-TX-toOpenROADM-5-4-SRG1-SRG1-PP4-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-5-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber29</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-5-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber30</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2</opposite-link>
+    <source><source-node>OpenROADM-5-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-3-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber31</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1</opposite-link>
+    <source><source-node>OpenROADM-5-3-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber32</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1</opposite-link>
+    <source><source-node>OpenROADM-5-3-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-4-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber33</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2</opposite-link>
+    <source><source-node>OpenROADM-5-4-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-3-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber34</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-5-4-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber35</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-4-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber36</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-1-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber37</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3</opposite-link>
+    <source><source-node>OpenROADM-2-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber38</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-1-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber39</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3</opposite-link>
+    <source><source-node>OpenROADM-2-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber40</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-2-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber41</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3</opposite-link>
+    <source><source-node>OpenROADM-3-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber42</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-2-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber43</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology"> 
+   <link-id>OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3</opposite-link>
+    <source><source-node>OpenROADM-3-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber44</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-3-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber45</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3</opposite-link>
+    <source><source-node>OpenROADM-4-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber46</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-3-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber47</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3</opposite-link>
+    <source><source-node>OpenROADM-4-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber48</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-4-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber49</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber50</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">10</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-4-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber51</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">10</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber52</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-4-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber53</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3</opposite-link>
+    <source><source-node>OpenROADM-1-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-4-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber54</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">10</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-3-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber55</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">10</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-1-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-3-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber56</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
 </network>
index 9252519c81a012fda2cb79d7b4e96803ec1f4bbb..d007741a03f678aee13ab028c5d136d9519d5bd2 100644 (file)
         <source><source-node>OpenROADM-1-2-SRG1</source-node><source-tp>SRG1-PP5-TX</source-tp></source>        <destination><dest-node>XPONDER-1-2</dest-node><dest-tp>XPDR-NW5-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-1-2XPDR-NW5-TX-toOpenROADM-1-2-SRG1-SRG1-PP5-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-1-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber1</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-1-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber2</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-1-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber3</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-    <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-2-1-DEG1-DEG1-CTP-TXtoOpenROADM-2-1-DEG2-DEG2-CTP-RX</link-id>
+    <source><source-node>OpenROADM-1-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber4</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-2-1-DEG1-DEG1-CTP-TXtoOpenROADM-2-1-DEG2-DEG2-CTP-RX</link-id>
         <source><source-node>OpenROADM-2-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-2-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG2-DEG2-CTP-TXtoOpenROADM-2-1-DEG1-DEG1-CTP-RX</opposite-link>
         <link-type xmlns="http://org/openroadm/network/topology">EXPRESS-LINK</link-type></link>
         <source><source-node>OpenROADM-2-2-SRG1</source-node><source-tp>SRG1-PP5-TX</source-tp></source>        <destination><dest-node>XPONDER-2-2</dest-node><dest-tp>XPDR-NW5-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-2-2XPDR-NW5-TX-toOpenROADM-2-2-SRG1-SRG1-PP5-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-2-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber5</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-2-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber6</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-2-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber7</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-2-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber8</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG2-DEG2-CTP-RX</link-id>
         <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-3-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG2-DEG2-CTP-TXtoOpenROADM-3-1-DEG1-DEG1-CTP-RX</opposite-link>
         <source><source-node>OpenROADM-3-2-SRG1</source-node><source-tp>SRG1-PP5-TX</source-tp></source>        <destination><dest-node>XPONDER-3-2</dest-node><dest-tp>XPDR-NW5-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-3-2XPDR-NW5-TX-toOpenROADM-3-2-SRG1-SRG1-PP5-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-3-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber9</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-3-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber10</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-3-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber11</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-3-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber12</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-4-1-DEG1-DEG1-CTP-TXtoOpenROADM-4-1-DEG2-DEG2-CTP-RX</link-id>
         <source><source-node>OpenROADM-4-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-4-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG2-DEG2-CTP-TXtoOpenROADM-4-1-DEG1-DEG1-CTP-RX</opposite-link>
         <source><source-node>OpenROADM-4-2-SRG1</source-node><source-tp>SRG1-PP5-TX</source-tp></source>        <destination><dest-node>XPONDER-4-2</dest-node><dest-tp>XPDR-NW5-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-4-2XPDR-NW5-TX-toOpenROADM-4-2-SRG1-SRG1-PP5-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-4-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber13</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-4-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber14</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-4-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber15</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-4-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber16</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">        <link-id>OpenROADM-5-1-DEG1-DEG1-CTP-TXtoOpenROADM-5-1-DEG2-DEG2-CTP-RX</link-id>
         <source><source-node>OpenROADM-5-1-DEG1</source-node><source-tp>DEG1-CTP-TX</source-tp></source>        <destination><dest-node>OpenROADM-5-1-DEG2</dest-node><dest-tp>DEG2-CTP-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG2-DEG2-CTP-TXtoOpenROADM-5-1-DEG1-DEG1-CTP-RX</opposite-link>
         <source><source-node>OpenROADM-5-2-SRG1</source-node><source-tp>SRG1-PP5-TX</source-tp></source>        <destination><dest-node>XPONDER-5-2</dest-node><dest-tp>XPDR-NW5-RX</dest-tp></destination>
         <opposite-link xmlns="http://org/openroadm/common/network">XPONDER-5-2XPDR-NW5-TX-toOpenROADM-5-2-SRG1-SRG1-PP5-RX</opposite-link>
        <link-type xmlns="http://org/openroadm/network/topology">XPONDER-INPUT</link-type></link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</opposite-link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</opposite-link>
+    <source><source-node>OpenROADM-5-1-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    
+    <destination><dest-node>OpenROADM-5-2-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber17</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2</opposite-link>
+    <source><source-node>OpenROADM-5-2-DEG1</source-node><source-tp>DEG1-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-1-DEG1</dest-node><dest-tp>DEG1-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber18</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2</opposite-link>
+    <source><source-node>OpenROADM-5-2-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-1-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber19</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-1-DEG2</source-node><source-tp>DEG2-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-2-DEG2</dest-node><dest-tp>DEG2-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber20</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-1-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber21</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-2-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber22</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-2-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-2-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber23</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-2-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-3-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-2-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber24</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-3-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-3-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber25</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-3-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-4-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-3-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber26</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-4-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-4-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber27</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    
+    <link-id>OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-4-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-4-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber28</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-5-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-1-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
-<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">    <link-id>OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3</link-id>    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3</opposite-link>
+    <source><source-node>OpenROADM-5-2-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-1-1-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber29</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
+<link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
+    <link-id>OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3</link-id>
+    <opposite-link xmlns="http://org/openroadm/common/network">OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3</opposite-link>
     <link-latency xmlns="http://org/openroadm/network/topology">1</link-latency>
     <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
-    <source><source-node>OpenROADM-1-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>    <destination><dest-node>OpenROADM-5-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>    </link>
+    <source><source-node>OpenROADM-1-1-DEG3</source-node><source-tp>DEG3-TTP-TX</source-tp></source>
+    <destination><dest-node>OpenROADM-5-2-DEG3</dest-node><dest-tp>DEG3-TTP-RX</dest-tp></destination>
+    <OMS-attributes xmlns="http://org/openroadm/network/topology">
+        <opposite-link>OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3</opposite-link>
+        <TE-metric>10</TE-metric>
+        <span>
+            <clfi>fiber30</clfi>
+            <auto-spanloss>true</auto-spanloss>
+            <spanloss-base>11.4</spanloss-base>
+            <spanloss-current>12</spanloss-current>
+            <engineered-spanloss>12.2</engineered-spanloss>
+            <link-concatenation>
+                <SRLG-Id>0</SRLG-Id>
+                <fiber-type>smf</fiber-type>
+                <SRLG-length>100000</SRLG-length>
+                <pmd>0.5</pmd>
+            </link-concatenation>
+        </span>
+    </OMS-attributes>
+</link>
 </network>
index 93a5922c33cac73c17773f7464166cd8cceae9b8..84dba1fd85f99288ca70173f443a4382999fc25c 100644 (file)
         </source>
         <OMS-attributes xmlns="http://org/openroadm/network/topology">
             <opposite-link>ROADMC-DEG2-DEG2-TTP-TXRXtoROADMA-DEG1-DEG1-TTP-TXRX</opposite-link>
+            <TE-metric>10</TE-metric>
+            <span>
+                <clfi>fiber1</clfi>
+                <auto-spanloss>true</auto-spanloss>
+                <spanloss-base>11.4</spanloss-base>
+                <spanloss-current>12</spanloss-current>
+                <engineered-spanloss>12.2</engineered-spanloss>
+                <link-concatenation>
+                    <SRLG-Id>0</SRLG-Id>
+                    <fiber-type>smf</fiber-type>
+                    <SRLG-length>100000</SRLG-length>
+                    <pmd>0.5</pmd>
+                </link-concatenation>
+            </span>
         </OMS-attributes>
         <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
+        <link-latency xmlns="http://org/openroadm/common/network">0</link-latency>
     </link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
         <link-id>ROADMA-SRG1-SRG1-PP1-TXRXtoXPDRA-XPDR1-XPDR1-NETWORK1</link-id>
         </source>
         <OMS-attributes xmlns="http://org/openroadm/network/topology">
             <opposite-link>ROADMA-DEG1-DEG1-TTP-TXRXtoROADMC-DEG2-DEG2-TTP-TXRX</opposite-link>
+            <TE-metric>10</TE-metric>
+            <span>
+                <clfi>fiber2</clfi>
+                <auto-spanloss>true</auto-spanloss>
+                <spanloss-base>11.4</spanloss-base>
+                <spanloss-current>12</spanloss-current>
+                <engineered-spanloss>12.2</engineered-spanloss>
+                <link-concatenation>
+                    <SRLG-Id>0</SRLG-Id>
+                    <fiber-type>smf</fiber-type>
+                    <SRLG-length>100000</SRLG-length>
+                    <pmd>0.5</pmd>
+                </link-concatenation>
+            </span>
         </OMS-attributes>
         <link-type xmlns="http://org/openroadm/network/topology">ROADM-TO-ROADM</link-type>
+        <link-latency xmlns="http://org/openroadm/common/network">0</link-latency>
     </link>
     <link xmlns="urn:ietf:params:xml:ns:yang:ietf-network-topology">
         <link-id>ROADMC-DEG1-DEG1-CTP-TXRXtoROADMC-SRG1-SRG1-CP-TXRX</link-id>