From 7c90be243c9c65418b81768e1e0ed6ac58bad4a8 Mon Sep 17 00:00:00 2001 From: shweta Date: Tue, 18 Jun 2019 13:12:49 -0400 Subject: [PATCH] PCE update to support constraints - 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 --- pce/pom.xml | 14 +- .../transportpce/pce/PceComplianceCheck.java | 9 +- .../transportpce/pce/PcePathDescription.java | 50 +- .../transportpce/pce/PceSendingPceRPCs.java | 129 +- .../pce/constraints/PceConstraints.java | 121 +- .../pce/constraints/PceConstraintsCalc.java | 207 ++- .../pce/gnpy/ExtractTopoDataStoreImpl.java | 28 +- .../transportpce/pce/gnpy/GnpyResult.java | 5 +- .../gnpy/ServiceDataStoreOperationsImpl.java | 4 +- .../pce/graph/InAlgoPathValidator.java | 235 +++ .../transportpce/pce/graph/PceGraph.java | 432 ++--- .../transportpce/pce/graph/PceGraphEdge.java | 27 + .../pce/graph/PostAlgoPathValidator.java | 83 + .../pce/impl/PceServiceRPCImpl.java | 4 +- .../pce/networkanalyzer/MapUtils.java | 84 +- .../pce/networkanalyzer/PceCalculation.java | 446 +++-- .../pce/{ => networkanalyzer}/PceLink.java | 160 +- .../pce/{ => networkanalyzer}/PceNode.java | 102 +- .../pce/{ => networkanalyzer}/PceResult.java | 57 +- .../service/PathComputationServiceImpl.java | 16 +- .../OSGI-INF/blueprint/pce-blueprint.xml | 4 +- tests/sample_configs/NW-for-test-5-4.xml | 1512 +++++++++++++++-- tests/sample_configs/NW-simple-topology.xml | 752 +++++++- tests/sample_configs/honeynode-topo.xml | 30 + 24 files changed, 3550 insertions(+), 961 deletions(-) mode change 100644 => 100755 pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java create mode 100644 pce/src/main/java/org/opendaylight/transportpce/pce/graph/InAlgoPathValidator.java create mode 100644 pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraphEdge.java create mode 100644 pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java rename pce/src/main/java/org/opendaylight/transportpce/pce/{ => networkanalyzer}/PceLink.java (61%) rename pce/src/main/java/org/opendaylight/transportpce/pce/{ => networkanalyzer}/PceNode.java (82%) rename pce/src/main/java/org/opendaylight/transportpce/pce/{ => networkanalyzer}/PceResult.java (66%) diff --git a/pce/pom.xml b/pce/pom.xml index d2f005162..d5ace4a22 100644 --- a/pce/pom.xml +++ b/pce/pom.xml @@ -61,9 +61,9 @@ Author: Martial Coulibaly on behalf of Orange ${project.version} - org.opendaylight.controller.thirdparty - net.sf.jung2 - 2.0.1 + org.jgrapht + jgrapht-core + 1.1.1-SNAPSHOT @@ -96,4 +96,12 @@ Author: Martial Coulibaly on behalf of Orange + + + browserid-snapshots + browserid-snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PceComplianceCheck.java b/pce/src/main/java/org/opendaylight/transportpce/pce/PceComplianceCheck.java index b4d13b5d7..b7c845027 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PceComplianceCheck.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/PceComplianceCheck.java @@ -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 { } } - diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PcePathDescription.java b/pce/src/main/java/org/opendaylight/transportpce/pce/PcePathDescription.java index 31486dbad..287e74ecc 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PcePathDescription.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/PcePathDescription.java @@ -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 pathAtoZ = null; private PceResult rc; public PceResult getReturnStructure() { - return this.rc; + return rc; } private Map 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 atozList = new ArrayList(); - 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 ztoaList = new ArrayList(); - 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 etoeList, List 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()); diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java b/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java old mode 100644 new mode 100755 index f05e23059..96161a249 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java @@ -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 elementsList1 = xtrTopo.getElements(); List 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 elementsList2 = xtrTopo.getElements(); List 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 elementsList, List connectionsList, List pathRequestList, List synchronizationList) throws Exception { GnpyApi gnpyApi = new GnpyApiBuilder() @@ -210,7 +212,7 @@ public class PceSendingPceRPCs { .setServiceFile(new ServiceFileBuilder().setPathRequest(pathRequestList).build()).build(); InstanceIdentifier 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() { diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraints.java b/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraints.java index 5e878e02f..b5e8c7978 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraints.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraints.java @@ -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 nodesToExclude = new ArrayList(); - private List srlgToExclude = new ArrayList(); + private List supNodesToExclude = new ArrayList(); + + private List srlgToExclude = new ArrayList(); + private List srlgLinksToExclude = new ArrayList(); + + private List clliToExclude = new ArrayList(); + private List clliNodesToExclude = new ArrayList(); private List nodesToInclude = new ArrayList(); private List pceNodesToInclude = new ArrayList(); + public static final Long CONST_OSNR = 1L; private double maxOSNR = (CONST_OSNR / (Math.pow(10, (24 / 10.0)))); + /**. + * /////////////// INCLUDE CONSTRAINTS./////////////////// + */ + private List listToInclude = new ArrayList(); + private List srlgNames = new ArrayList(); + + 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 getExcludeNodes() { - LOG.debug("in Pceconstraints getExcludeNodes size = {}", nodesToExclude.size()); - return nodesToExclude; + // Exclude nodes / SRLD / CLLI + + public List getExcludeSupNodes() { + LOG.debug("in Pceconstraints getExcludeSupNodes size = {}", supNodesToExclude.size()); + return supNodesToExclude; } - public void setExcludeNodes(List nodes) { - LOG.debug("in Pceconstraints setExcludeNodes size = {}", nodes.size()); - nodesToExclude.addAll(nodes); + public void setExcludeSupNodes(List supNodes) { + LOG.debug("in Pceconstraints setExcludeSupNodes size = {}", supNodes.size()); + supNodesToExclude.addAll(supNodes); } - public List getExcludeSRLG() { + public List getExcludeSRLG() { LOG.debug("in Pceconstraints getExcludeSRLG size = {}", srlgToExclude.size()); return srlgToExclude; } - public void setExcludeSRLG(List srlg) { - LOG.debug("in Pceconstraints setExcludeSRLG size = {}", srlg.size()); + public void setExcludeSRLG(List srlg) { + LOG.info("in Pceconstraints setExcludeSRLG size = {}", srlg.size()); srlgToExclude.addAll(srlg); } + public List getExcludeCLLI() { + LOG.debug("in Pceconstraints getExcludeCLLI size = {}", clliToExclude.size()); + return clliToExclude; + } + + public void setExcludeCLLI(List 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 getExcludeClliNodes() { + LOG.info("in Pceconstraints getExcludeClliNodes size = {}", clliNodesToExclude.size()); + return clliNodesToExclude; + } + + public void setExcludeClliNodes(List clli) { + LOG.debug("in Pceconstraints setExcludeCLLI size = {}", clli.size()); + clliNodesToExclude.addAll(clli); + } + + public List getExcludeSrlgLinks() { + LOG.info("in Pceconstraints getExcludeSrlgNodes size = {}", srlgLinksToExclude.size()); + return srlgLinksToExclude; + } + + public void setExcludeSrlgLinks(List srlg) { + LOG.debug("in Pceconstraints setExcludeSRLG size = {}", srlg.size()); + srlgLinksToExclude.addAll(srlg); + } + + public List getExcludeNodes() { + LOG.info("in Pceconstraints getExcludeNodes size = {}", nodesToExclude.size()); + return nodesToExclude; + } + + public void setExcludeNodes(List nodes) { + LOG.debug("in Pceconstraints setExcludeNodes size = {}", nodes.size()); + nodesToExclude.addAll(nodes); + } // Include nodes public List 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 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 getSRLGnames() { + return srlgNames; + } } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java b/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java index ae6b8d561..1b8372ef6 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java @@ -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 srlgToExclude = new ArrayList(); + 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 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 srvList, PceConstraints constraints) { + private void readIncludeNodes(List 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 srvList, PceConstraints constraints, PceConstraints.ResourceType rt) { List elementsToExclude = new ArrayList(); - LOG.info("in readDiversityNodes {}", srvList.toString()); + LOG.info("in readDiversity {}", srvList.toString()); for (String srv : srvList) { Optional 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 getAToZNodeList(PathDescription pathDescription) { - List atozList = pathDescription.getAToZDirection().getAToZ(); - return atozList.stream().filter(aToZ -> { - if ((aToZ.getResource() == null) || (aToZ.getResource().getResource() == null)) { + List 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 getSRLGList(PathDescription pathDescription) { + List 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 getPathDescriptionFromDatastore(String serviceName) { Optional result = Optional.absent(); InstanceIdentifier 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; } - } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ExtractTopoDataStoreImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ExtractTopoDataStoreImpl.java index 5c0d4031b..09c8511b2 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ExtractTopoDataStoreImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ExtractTopoDataStoreImpl.java @@ -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 = new ArrayList<>(); private List connections = new ArrayList<>(); private List 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> map = extractTopo(); if (map.containsKey("Elements")) { elements = (List) 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> map = extractTopo(); if (map.containsKey("Elements")) { elements = (List) map.get("Elements"); @@ -174,15 +173,14 @@ public class ExtractTopoDataStoreImpl { InstanceIdentifier 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 openRoadmTopo = readOnlyTransaction + java.util.Optional openRoadmTopo = this.networkTransactionService .read(LogicalDatastoreType.CONFIGURATION, insIdOpenRoadmTopo).get().toJavaUtil(); - java.util.Optional openRoadmNet = readOnlyTransaction + java.util.Optional openRoadmNet = this.networkTransactionService .read(LogicalDatastoreType.CONFIGURATION, insIdrOpenRoadmNet).get().toJavaUtil(); if (openRoadmNet.isPresent()) { List 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; diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java index 338624a2d..4aa3131b8 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java @@ -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 pathMetricList = noPathCase.getNoPath().getPathProperties().getPathMetric(); LOG.info("GNPy : path is not feasible : {}", noPathType); for (PathMetric pathMetric : pathMetricList) { diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java index c25f82d33..212985aa3 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java @@ -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 index 000000000..19f6049d1 --- /dev/null +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/InAlgoPathValidator.java @@ -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 { + /* 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 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 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 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 partialPath, + PceGraphEdge edge, PceNode zendNodeInput, + PceConstraints pceHardConstraintsInput) { + + List 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 pathEdges = partialPath.getEdgeList(); + pathEdges.add(edge); + LOG.info(" in checkInclude vertex list: [{}]", partialPath.getVertexList()); + + List listOfElementsSubNode = new ArrayList(); + listOfElementsSubNode.add(pathEdges.get(0).link().getsourceSupNodeId()); + listOfElementsSubNode.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.NODE)); + + List listOfElementsCLLI = new ArrayList(); + listOfElementsCLLI.add(pathEdges.get(0).link().getsourceCLLI()); + listOfElementsCLLI.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.CLLI)); + + List listOfElementsSRLG = new ArrayList(); + 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 listOfElementsBuild(List pathEdges, PceConstraints.ResourceType type) { + List listOfElements = new ArrayList(); + + 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. 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; + } +} diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraph.java b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraph.java index 08886ca87..0aeadeb29 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraph.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraph.java @@ -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 nwGraph = new DirectedSparseMultigraph(); - private DijkstraShortestPath shortestPath = null; + int kpathsToBring = 10; // how many paths to bring + int mhopsPerPath = 50; // max #hops // input private Map allPceNodes = new HashMap(); @@ -43,20 +49,10 @@ public class PceGraph { private PceResult pceResult = null; private List shortestPathAtoZ = null; - // TODO hard-coded 96 - private static final int MAX_WAWELENGTH = 96; - // for path calculation - private List pathAtoZ = null; - private int minFoundDistance; - private int tmpAtozDistance = 0; - private int tmpAtozLatency = 0; - private int bestDistance; - private boolean noPathExists = false; + List> allWPaths = null; - private boolean foundButTooHighLatency = false; - - private List listOfNodesPerWL = new ArrayList(); + private List pathAtoZ = new ArrayList(); public PceGraph(PceNode aendNode, PceNode zendNode, Map 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 weightedGraph = + new DefaultDirectedWeightedGraph(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 path : allWPaths) { - for (int i = 1; i <= MAX_WAWELENGTH; i++) { - LOG.info(" In PCE GRAPH : FUll algorithm for WL {}", i); - List 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 allNodes) { - - cleanupGraph(); - Iterator> nodes = allNodes.entrySet().iterator(); - while (nodes.hasNext()) { - Map.Entry node = nodes.next(); - PceNode pcenode = node.getValue(); - List 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 allNodes) { - - cleanupGraph(); - - for (PceNode node : allNodes) { - List 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 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 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 swp = + new KShortestPaths(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 calcAlgo() { - - Transformer wtTransformer = new Transformer() { - @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 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 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 listOfNodes = new ArrayList(); - - private void addNodetoWL(PceNode node) { - this.listOfNodes.add(node); - } - - private List getNodes() { - return this.listOfNodes; + private void populateWithNodes(DefaultDirectedWeightedGraph weightedGraph) { + Iterator> nodes = allPceNodes.entrySet().iterator(); + while (nodes.hasNext()) { + Map.Entry node = nodes.next(); + weightedGraph.addVertex(node.getValue().getNodeId().getValue()); + LOG.debug("In populateWithNodes in node : {}", node.getValue().toString()); } - } - private boolean extractWLs(Map allNodes) { + private boolean populateWithLinks(DefaultDirectedWeightedGraph weightedGraph) { - Iterator> nodes = allNodes.entrySet().iterator(); + Iterator> nodes = allPceNodes.entrySet().iterator(); while (nodes.hasNext()) { Map.Entry node = nodes.next(); PceNode pcenode = node.getValue(); - List 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 toRemove = new ArrayList(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 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 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 index 000000000..78861c5e7 --- /dev/null +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraphEdge.java @@ -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 index 000000000..55ea21b5f --- /dev/null +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java @@ -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 path, + Map 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 path, Map 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 path) { + double localOsnr = 0L; + for (PceGraphEdge edge : path.getEdgeList()) { + localOsnr = localOsnr + edge.link().getosnr(); + } + LOG.info("In OSNR Stub: {}", localOsnr); + return true; + } +} diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/impl/PceServiceRPCImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/impl/PceServiceRPCImpl.java index f72385b9b..e201199c5 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/impl/PceServiceRPCImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/impl/PceServiceRPCImpl.java @@ -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 diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java index d3985f004..6ee3043d8 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java @@ -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 allNodes, List allLinks, + PceConstraints pceHardConstraints) { + List excClliNodes = pceHardConstraints.getExcludeClliNodes(); + List excNodes = pceHardConstraints.getExcludeNodes(); + List 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 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 getSRLG(Link link) { List srlgList = new ArrayList(); - Span span = getOmsAttributesSpan(link); - if (span != null) { - List linkList = span.getLinkConcatenation(); + try { + List 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; + } + + } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java index 80c1cc2d0..7ce9b80d1 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java @@ -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 addLinks = new ArrayList(); private List dropLinks = new ArrayList(); private HashSet azSrgs = new HashSet(); + private PceNode aendPceNode = null; private PceNode zendPceNode = null; + private List allLinks = null; private List allNodes = null; + // this List serves graph calculation private Map allPceNodes = new HashMap(); // this List serves calculation of ZtoA path descritopn // TODO maybe better solution is possible private Map allPceLinks = new HashMap(); + private Set linksToExclude = new HashSet(); 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 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 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 constraints = new ArrayList(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 getAllPceNodes() { @@ -415,4 +468,25 @@ public class PceCalculation { public Map getAllPceLinks() { return this.allPceLinks; } + + public PceResult getReturnStructure() { + return returnStructure; + } + + private static void printNodesInfo(Map allpcenodes) { + Iterator> nodes = allpcenodes.entrySet().iterator(); + while (nodes.hasNext()) { + PceNode pcenode = nodes.next().getValue(); + List links = pcenode.getOutgoingLinks(); + LOG.info("In printNodes in node {} : outgoing links {} ", pcenode.getNodeId().getValue(), links.toString()); + } + } + + private static void printLinksInfo(Map allpcelinks) { + Iterator> links = allpcelinks.entrySet().iterator(); + while (links.hasNext()) { + LOG.info("In printLinksInfo link {} : ", links.next().getValue().toString()); + } + } + } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PceLink.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java 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 6320d9e53..72adcb7f9 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PceLink.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java @@ -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 srlg; + private final List 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 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; } } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PceNode.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceNode.java 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 57797640e..2fcc5df57 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PceNode.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceNode.java @@ -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 availableWLindex = new ArrayList(); private Map availableSrgPp = new TreeMap(); @@ -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 getAvailableWLs() { - return this.availableWLindex; + return availableWLindex; } public void addOutgoingLink(PceLink outLink) { @@ -277,15 +347,31 @@ public class PceNode { } public List 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()); + } + } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PceResult.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceResult.java 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 b7119d898..233d785d8 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PceResult.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceResult.java @@ -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; } - } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java index dd4ec8a28..48a19ef46 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java @@ -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 listResponse = new ArrayList<>(); @@ -256,4 +257,5 @@ public class PathComputationServiceImpl implements PathComputationService { .setFeasibility(feasible).build(); return gnpypResp; } -} + +} \ No newline at end of file diff --git a/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml b/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml index 6b0dbb68c..7560106a0 100755 --- a/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml +++ b/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml @@ -13,6 +13,8 @@ Author: Martial Coulibaly on behalf of Orange xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" odl:use-default-for-reference-types="true"> + + @@ -27,7 +29,7 @@ Author: Martial Coulibaly on behalf of Orange - + diff --git a/tests/sample_configs/NW-for-test-5-4.xml b/tests/sample_configs/NW-for-test-5-4.xml index 8457c2e6b..62185064f 100644 --- a/tests/sample_configs/NW-for-test-5-4.xml +++ b/tests/sample_configs/NW-for-test-5-4.xml @@ -2280,38 +2280,206 @@ OpenROADM-1-4-SRG1SRG1-PP4-TX XPONDER-1-4XPDR-NW4-RX XPONDER-1-4XPDR-NW4-TX-toOpenROADM-1-4-SRG1-SRG1-PP4-RX XPONDER-INPUT - OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 + + OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 + OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-1-1-DEG1DEG1-TTP-TX OpenROADM-1-2-DEG1DEG1-TTP-RX - OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 + OpenROADM-1-1-DEG1DEG1-TTP-TX + OpenROADM-1-2-DEG1DEG1-TTP-RX + + OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 + 10 + + fiber1 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 + OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-1-2-DEG1DEG1-TTP-TX OpenROADM-1-1-DEG1DEG1-TTP-RX - OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2 OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2 + OpenROADM-1-2-DEG1DEG1-TTP-TX + OpenROADM-1-1-DEG1DEG1-TTP-RX + + OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 + 10 + + fiber2 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2 + OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-1-2-DEG2DEG2-TTP-TX OpenROADM-1-3-DEG2DEG2-TTP-RX - OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2 OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2 + OpenROADM-1-2-DEG2DEG2-TTP-TX + OpenROADM-1-3-DEG2DEG2-TTP-RX + + OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2 + 10 + + fiber56 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-3-DEG2-to-OpenROADM-1-2-DEG2 + OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2 1 ROADM-TO-ROADM - OpenROADM-1-3-DEG2DEG2-TTP-TX OpenROADM-1-2-DEG2DEG2-TTP-RX - OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1 OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1 + OpenROADM-1-3-DEG2DEG2-TTP-TX + OpenROADM-1-2-DEG2DEG2-TTP-RX + + OpenROADM-1-2-DEG2-to-OpenROADM-1-3-DEG2 + 10 + + fiber3 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1 + OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1 1 ROADM-TO-ROADM - OpenROADM-1-3-DEG1DEG1-TTP-TX OpenROADM-1-4-DEG1DEG1-TTP-RX - OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1 OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1 + OpenROADM-1-3-DEG1DEG1-TTP-TX + OpenROADM-1-4-DEG1DEG1-TTP-RX + + OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1 + 10 + + fiber + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-4-DEG1-to-OpenROADM-1-3-DEG1 + OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1 1 ROADM-TO-ROADM - OpenROADM-1-4-DEG1DEG1-TTP-TX OpenROADM-1-3-DEG1DEG1-TTP-RX - OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2 OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2 + OpenROADM-1-4-DEG1DEG1-TTP-TX + OpenROADM-1-3-DEG1DEG1-TTP-RX + + OpenROADM-1-3-DEG1-to-OpenROADM-1-4-DEG1 + 10 + + fiber4 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2 + OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2 1 ROADM-TO-ROADM - OpenROADM-1-4-DEG2DEG2-TTP-TX OpenROADM-1-1-DEG2DEG2-TTP-RX - OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2 OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2 + OpenROADM-1-4-DEG2DEG2-TTP-TX + OpenROADM-1-1-DEG2DEG2-TTP-RX + + OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2 + 10 + + fiber57 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-1-DEG2-to-OpenROADM-1-4-DEG2 + OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-1-1-DEG2DEG2-TTP-TX OpenROADM-1-4-DEG2DEG2-TTP-RX + OpenROADM-1-1-DEG2DEG2-TTP-TX + OpenROADM-1-4-DEG2DEG2-TTP-RX + + OpenROADM-1-4-DEG2-to-OpenROADM-1-1-DEG2 + 10 + + fiber5 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + OpenROADM-2-1-DEG1-DEG1-CTP-TXtoOpenROADM-2-1-DEG2-DEG2-CTP-RX OpenROADM-2-1-DEG1DEG1-CTP-TX OpenROADM-2-1-DEG2DEG2-CTP-RX OpenROADM-2-1-DEG2-DEG2-CTP-TXtoOpenROADM-2-1-DEG1-DEG1-CTP-RX @@ -2632,43 +2800,215 @@ OpenROADM-2-4-SRG1SRG1-PP4-TX XPONDER-2-4XPDR-NW4-RX XPONDER-2-4XPDR-NW4-TX-toOpenROADM-2-4-SRG1-SRG1-PP4-RX XPONDER-INPUT - OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 + + OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 + OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-2-1-DEG1DEG1-TTP-TX OpenROADM-2-2-DEG1DEG1-TTP-RX - OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 + OpenROADM-2-1-DEG1DEG1-TTP-TX + OpenROADM-2-2-DEG1DEG1-TTP-RX + + OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 + 10 + + fiber6 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 + OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-2-2-DEG1DEG1-TTP-TX OpenROADM-2-1-DEG1DEG1-TTP-RX - OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2 OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2 + OpenROADM-2-2-DEG1DEG1-TTP-TX + OpenROADM-2-1-DEG1DEG1-TTP-RX + + OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 + 10 + + fiber7 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2 + OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-2-2-DEG2DEG2-TTP-TX OpenROADM-2-3-DEG2DEG2-TTP-RX - OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2 OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2 + OpenROADM-2-2-DEG2DEG2-TTP-TX + OpenROADM-2-3-DEG2DEG2-TTP-RX + + OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2 + 10 + + fiber8 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-3-DEG2-to-OpenROADM-2-2-DEG2 + OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2 1 ROADM-TO-ROADM - OpenROADM-2-3-DEG2DEG2-TTP-TX OpenROADM-2-2-DEG2DEG2-TTP-RX - OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1 OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1 + OpenROADM-2-3-DEG2DEG2-TTP-TX + OpenROADM-2-2-DEG2DEG2-TTP-RX + + OpenROADM-2-2-DEG2-to-OpenROADM-2-3-DEG2 + 10 + + fiber9 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1 + OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1 1 ROADM-TO-ROADM - OpenROADM-2-3-DEG1DEG1-TTP-TX OpenROADM-2-4-DEG1DEG1-TTP-RX - OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1 OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1 + OpenROADM-2-3-DEG1DEG1-TTP-TX + OpenROADM-2-4-DEG1DEG1-TTP-RX + + OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1 + 10 + + fiber10 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-4-DEG1-to-OpenROADM-2-3-DEG1 + OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1 1 ROADM-TO-ROADM - OpenROADM-2-4-DEG1DEG1-TTP-TX OpenROADM-2-3-DEG1DEG1-TTP-RX - OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2 OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2 + OpenROADM-2-4-DEG1DEG1-TTP-TX + OpenROADM-2-3-DEG1DEG1-TTP-RX + + OpenROADM-2-3-DEG1-to-OpenROADM-2-4-DEG1 + 10 + + fiber11 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2 + OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2 1 ROADM-TO-ROADM - OpenROADM-2-4-DEG2DEG2-TTP-TX OpenROADM-2-1-DEG2DEG2-TTP-RX - OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2 OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2 + OpenROADM-2-4-DEG2DEG2-TTP-TX + OpenROADM-2-1-DEG2DEG2-TTP-RX + + OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2 + 10 + + fiber58 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-1-DEG2-to-OpenROADM-2-4-DEG2 + OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-2-1-DEG2DEG2-TTP-TX OpenROADM-2-4-DEG2DEG2-TTP-RX - OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG2-DEG2-CTP-RX - OpenROADM-3-1-DEG1DEG1-CTP-TX OpenROADM-3-1-DEG2DEG2-CTP-RX + OpenROADM-2-1-DEG2DEG2-TTP-TX + OpenROADM-2-4-DEG2DEG2-TTP-RX + + OpenROADM-2-4-DEG2-to-OpenROADM-2-1-DEG2 + 10 + + fiber12 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG2-DEG2-CTP-RX + OpenROADM-3-1-DEG1DEG1-CTP-TX + OpenROADM-3-1-DEG2DEG2-CTP-RX OpenROADM-3-1-DEG2-DEG2-CTP-TXtoOpenROADM-3-1-DEG1-DEG1-CTP-RX - EXPRESS-LINK - OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG3-DEG3-CTP-RX + EXPRESS-LINK + + + OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG3-DEG3-CTP-RX OpenROADM-3-1-DEG1DEG1-CTP-TX OpenROADM-3-1-DEG3DEG3-CTP-RX OpenROADM-3-1-DEG3-DEG3-CTP-TXtoOpenROADM-3-1-DEG1-DEG1-CTP-RX EXPRESS-LINK @@ -2984,38 +3324,206 @@ OpenROADM-3-4-SRG1SRG1-PP4-TX XPONDER-3-4XPDR-NW4-RX XPONDER-3-4XPDR-NW4-TX-toOpenROADM-3-4-SRG1-SRG1-PP4-RX XPONDER-INPUT - OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 + + OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 + OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-3-1-DEG1DEG1-TTP-TX OpenROADM-3-2-DEG1DEG1-TTP-RX - OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 + OpenROADM-3-1-DEG1DEG1-TTP-TX + OpenROADM-3-2-DEG1DEG1-TTP-RX + + OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 + 10 + + fiber13 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 + OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-3-2-DEG1DEG1-TTP-TX OpenROADM-3-1-DEG1DEG1-TTP-RX - OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2 OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2 + OpenROADM-3-2-DEG1DEG1-TTP-TX + OpenROADM-3-1-DEG1DEG1-TTP-RX + + OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 + 10 + + fiber14 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2 + OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-3-2-DEG2DEG2-TTP-TX OpenROADM-3-3-DEG2DEG2-TTP-RX - OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2 OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2 + OpenROADM-3-2-DEG2DEG2-TTP-TX + OpenROADM-3-3-DEG2DEG2-TTP-RX + + OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2 + 10 + + fiber15 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-3-DEG2-to-OpenROADM-3-2-DEG2 + OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2 1 ROADM-TO-ROADM - OpenROADM-3-3-DEG2DEG2-TTP-TX OpenROADM-3-2-DEG2DEG2-TTP-RX - OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1 OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1 + OpenROADM-3-3-DEG2DEG2-TTP-TX + OpenROADM-3-2-DEG2DEG2-TTP-RX + + OpenROADM-3-2-DEG2-to-OpenROADM-3-3-DEG2 + 10 + + fiber16 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1 + OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1 1 ROADM-TO-ROADM - OpenROADM-3-3-DEG1DEG1-TTP-TX OpenROADM-3-4-DEG1DEG1-TTP-RX - OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1 OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1 + OpenROADM-3-3-DEG1DEG1-TTP-TX + OpenROADM-3-4-DEG1DEG1-TTP-RX + + OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1 + 10 + + fiber17 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-4-DEG1-to-OpenROADM-3-3-DEG1 + OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1 1 ROADM-TO-ROADM - OpenROADM-3-4-DEG1DEG1-TTP-TX OpenROADM-3-3-DEG1DEG1-TTP-RX - OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2 OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2 + OpenROADM-3-4-DEG1DEG1-TTP-TX + OpenROADM-3-3-DEG1DEG1-TTP-RX + + OpenROADM-3-3-DEG1-to-OpenROADM-3-4-DEG1 + 10 + + fiber18 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2 + OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2 1 ROADM-TO-ROADM - OpenROADM-3-4-DEG2DEG2-TTP-TX OpenROADM-3-1-DEG2DEG2-TTP-RX - OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2 OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2 + OpenROADM-3-4-DEG2DEG2-TTP-TX + OpenROADM-3-1-DEG2DEG2-TTP-RX + + OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2 + 10 + + fiber19 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-1-DEG2-to-OpenROADM-3-4-DEG2 + OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-3-1-DEG2DEG2-TTP-TX OpenROADM-3-4-DEG2DEG2-TTP-RX + OpenROADM-3-1-DEG2DEG2-TTP-TX + OpenROADM-3-4-DEG2DEG2-TTP-RX + + OpenROADM-3-4-DEG2-to-OpenROADM-3-1-DEG2 + 10 + + fiber20 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + OpenROADM-4-1-DEG1-DEG1-CTP-TXtoOpenROADM-4-1-DEG2-DEG2-CTP-RX OpenROADM-4-1-DEG1DEG1-CTP-TX OpenROADM-4-1-DEG2DEG2-CTP-RX OpenROADM-4-1-DEG2-DEG2-CTP-TXtoOpenROADM-4-1-DEG1-DEG1-CTP-RX @@ -3336,38 +3844,206 @@ OpenROADM-4-4-SRG1SRG1-PP4-TX XPONDER-4-4XPDR-NW4-RX XPONDER-4-4XPDR-NW4-TX-toOpenROADM-4-4-SRG1-SRG1-PP4-RX XPONDER-INPUT - OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 + + OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 + OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-4-1-DEG1DEG1-TTP-TX OpenROADM-4-2-DEG1DEG1-TTP-RX - OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 + OpenROADM-4-1-DEG1DEG1-TTP-TX + OpenROADM-4-2-DEG1DEG1-TTP-RX + + OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 + 10 + + fiber21 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 + OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-4-2-DEG1DEG1-TTP-TX OpenROADM-4-1-DEG1DEG1-TTP-RX - OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2 OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2 + OpenROADM-4-2-DEG1DEG1-TTP-TX + OpenROADM-4-1-DEG1DEG1-TTP-RX + + OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 + 10 + + fiber22 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2 + OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-4-2-DEG2DEG2-TTP-TX OpenROADM-4-3-DEG2DEG2-TTP-RX - OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2 OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2 + OpenROADM-4-2-DEG2DEG2-TTP-TX + OpenROADM-4-3-DEG2DEG2-TTP-RX + + OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2 + 10 + + fiber23 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-3-DEG2-to-OpenROADM-4-2-DEG2 + OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2 1 ROADM-TO-ROADM - OpenROADM-4-3-DEG2DEG2-TTP-TX OpenROADM-4-2-DEG2DEG2-TTP-RX - OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1 OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1 + OpenROADM-4-3-DEG2DEG2-TTP-TX + OpenROADM-4-2-DEG2DEG2-TTP-RX + + OpenROADM-4-2-DEG2-to-OpenROADM-4-3-DEG2 + 10 + + fiber24 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1 + OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1 1 ROADM-TO-ROADM - OpenROADM-4-3-DEG1DEG1-TTP-TX OpenROADM-4-4-DEG1DEG1-TTP-RX - OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1 OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1 + OpenROADM-4-3-DEG1DEG1-TTP-TX + OpenROADM-4-4-DEG1DEG1-TTP-RX + + OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1 + 10 + + fiber25 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-4-DEG1-to-OpenROADM-4-3-DEG1 + OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1 1 ROADM-TO-ROADM - OpenROADM-4-4-DEG1DEG1-TTP-TX OpenROADM-4-3-DEG1DEG1-TTP-RX - OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2 OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2 + OpenROADM-4-4-DEG1DEG1-TTP-TX + OpenROADM-4-3-DEG1DEG1-TTP-RX + + OpenROADM-4-3-DEG1-to-OpenROADM-4-4-DEG1 + 10 + + fiber26 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2 + OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2 1 ROADM-TO-ROADM - OpenROADM-4-4-DEG2DEG2-TTP-TX OpenROADM-4-1-DEG2DEG2-TTP-RX - OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2 OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2 + OpenROADM-4-4-DEG2DEG2-TTP-TX + OpenROADM-4-1-DEG2DEG2-TTP-RX + + OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2 + 10 + + fiber27 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-1-DEG2-to-OpenROADM-4-4-DEG2 + OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-4-1-DEG2DEG2-TTP-TX OpenROADM-4-4-DEG2DEG2-TTP-RX + OpenROADM-4-1-DEG2DEG2-TTP-TX + OpenROADM-4-4-DEG2DEG2-TTP-RX + + OpenROADM-4-4-DEG2-to-OpenROADM-4-1-DEG2 + 10 + + fiber28 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + OpenROADM-5-1-DEG1-DEG1-CTP-TXtoOpenROADM-5-1-DEG2-DEG2-CTP-RX OpenROADM-5-1-DEG1DEG1-CTP-TX OpenROADM-5-1-DEG2DEG2-CTP-RX OpenROADM-5-1-DEG2-DEG2-CTP-TXtoOpenROADM-5-1-DEG1-DEG1-CTP-RX @@ -3688,116 +4364,704 @@ OpenROADM-5-4-SRG1SRG1-PP4-TX XPONDER-5-4XPDR-NW4-RX XPONDER-5-4XPDR-NW4-TX-toOpenROADM-5-4-SRG1-SRG1-PP4-RX XPONDER-INPUT - OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 + + OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 + OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-5-1-DEG1DEG1-TTP-TX OpenROADM-5-2-DEG1DEG1-TTP-RX - OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 + OpenROADM-5-1-DEG1DEG1-TTP-TX + OpenROADM-5-2-DEG1DEG1-TTP-RX + + OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 + 10 + + fiber29 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 + OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-5-2-DEG1DEG1-TTP-TX OpenROADM-5-1-DEG1DEG1-TTP-RX - OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2 OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2 + OpenROADM-5-2-DEG1DEG1-TTP-TX + OpenROADM-5-1-DEG1DEG1-TTP-RX + + OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 + 10 + + fiber30 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2 + OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-5-2-DEG2DEG2-TTP-TX OpenROADM-5-3-DEG2DEG2-TTP-RX - OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2 OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2 + OpenROADM-5-2-DEG2DEG2-TTP-TX + OpenROADM-5-3-DEG2DEG2-TTP-RX + + OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2 + 10 + + fiber31 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-3-DEG2-to-OpenROADM-5-2-DEG2 + OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2 1 ROADM-TO-ROADM - OpenROADM-5-3-DEG2DEG2-TTP-TX OpenROADM-5-2-DEG2DEG2-TTP-RX - OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1 OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1 + OpenROADM-5-3-DEG2DEG2-TTP-TX + OpenROADM-5-2-DEG2DEG2-TTP-RX + + OpenROADM-5-2-DEG2-to-OpenROADM-5-3-DEG2 + 10 + + fiber32 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1 + OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1 1 ROADM-TO-ROADM - OpenROADM-5-3-DEG1DEG1-TTP-TX OpenROADM-5-4-DEG1DEG1-TTP-RX - OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1 OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1 + OpenROADM-5-3-DEG1DEG1-TTP-TX + OpenROADM-5-4-DEG1DEG1-TTP-RX + + OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1 + 10 + + fiber33 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-4-DEG1-to-OpenROADM-5-3-DEG1 + OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1 1 ROADM-TO-ROADM - OpenROADM-5-4-DEG1DEG1-TTP-TX OpenROADM-5-3-DEG1DEG1-TTP-RX - OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2 OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2 + OpenROADM-5-4-DEG1DEG1-TTP-TX + OpenROADM-5-3-DEG1DEG1-TTP-RX + + OpenROADM-5-3-DEG1-to-OpenROADM-5-4-DEG1 + 10 + + fiber34 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2 + OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2 1 ROADM-TO-ROADM - OpenROADM-5-4-DEG2DEG2-TTP-TX OpenROADM-5-1-DEG2DEG2-TTP-RX - OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2 OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2 + OpenROADM-5-4-DEG2DEG2-TTP-TX + OpenROADM-5-1-DEG2DEG2-TTP-RX + + OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2 + 10 + + fiber35 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-1-DEG2-to-OpenROADM-5-4-DEG2 + OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-5-1-DEG2DEG2-TTP-TX OpenROADM-5-4-DEG2DEG2-TTP-RX - OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3 OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3 + OpenROADM-5-1-DEG2DEG2-TTP-TX + OpenROADM-5-4-DEG2DEG2-TTP-RX + + OpenROADM-5-4-DEG2-to-OpenROADM-5-1-DEG2 + 10 + + fiber36 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3 + OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3 1 ROADM-TO-ROADM - OpenROADM-1-4-DEG3DEG3-TTP-TX OpenROADM-2-1-DEG3DEG3-TTP-RX - OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3 OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3 + OpenROADM-1-4-DEG3DEG3-TTP-TX + OpenROADM-2-1-DEG3DEG3-TTP-RX + + OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3 + 10 + + fiber37 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-1-DEG3-to-OpenROADM-1-4-DEG3 + OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-2-1-DEG3DEG3-TTP-TX OpenROADM-1-4-DEG3DEG3-TTP-RX - OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3 OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3 + OpenROADM-2-1-DEG3DEG3-TTP-TX + OpenROADM-1-4-DEG3DEG3-TTP-RX + + OpenROADM-1-4-DEG3-to-OpenROADM-2-1-DEG3 + 10 + + fiber38 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3 + OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3 1 ROADM-TO-ROADM - OpenROADM-1-3-DEG3DEG3-TTP-TX OpenROADM-2-2-DEG3DEG3-TTP-RX - OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3 OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3 + OpenROADM-1-3-DEG3DEG3-TTP-TX + OpenROADM-2-2-DEG3DEG3-TTP-RX + + OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3 + 10 + + fiber39 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-2-DEG3-to-OpenROADM-1-3-DEG3 + OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-2-2-DEG3DEG3-TTP-TX OpenROADM-1-3-DEG3DEG3-TTP-RX - OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3 OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3 + OpenROADM-2-2-DEG3DEG3-TTP-TX + OpenROADM-1-3-DEG3DEG3-TTP-RX + + OpenROADM-1-3-DEG3-to-OpenROADM-2-2-DEG3 + 10 + + fiber40 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3 + OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3 1 ROADM-TO-ROADM - OpenROADM-2-4-DEG3DEG3-TTP-TX OpenROADM-3-1-DEG3DEG3-TTP-RX - OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3 OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3 + OpenROADM-2-4-DEG3DEG3-TTP-TX + OpenROADM-3-1-DEG3DEG3-TTP-RX + + OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3 + 10 + + fiber41 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-1-DEG3-to-OpenROADM-2-4-DEG3 + OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-3-1-DEG3DEG3-TTP-TX OpenROADM-2-4-DEG3DEG3-TTP-RX - OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3 OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3 + OpenROADM-3-1-DEG3DEG3-TTP-TX + OpenROADM-2-4-DEG3DEG3-TTP-RX + + OpenROADM-2-4-DEG3-to-OpenROADM-3-1-DEG3 + 10 + + fiber42 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3 + OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3 1 ROADM-TO-ROADM - OpenROADM-2-3-DEG3DEG3-TTP-TX OpenROADM-3-2-DEG3DEG3-TTP-RX - OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3 OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3 + OpenROADM-2-3-DEG3DEG3-TTP-TX + OpenROADM-3-2-DEG3DEG3-TTP-RX + + OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3 + 10 + + fiber43 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-2-DEG3-to-OpenROADM-2-3-DEG3 + OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-3-2-DEG3DEG3-TTP-TX OpenROADM-2-3-DEG3DEG3-TTP-RX - OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3 OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3 + OpenROADM-3-2-DEG3DEG3-TTP-TX + OpenROADM-2-3-DEG3DEG3-TTP-RX + + OpenROADM-2-3-DEG3-to-OpenROADM-3-2-DEG3 + 10 + + fiber44 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3 + OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3 1 ROADM-TO-ROADM - OpenROADM-3-4-DEG3DEG3-TTP-TX OpenROADM-4-1-DEG3DEG3-TTP-RX - OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3 OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3 + OpenROADM-3-4-DEG3DEG3-TTP-TX + OpenROADM-4-1-DEG3DEG3-TTP-RX + + OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3 + 10 + + fiber45 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-1-DEG3-to-OpenROADM-3-4-DEG3 + OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-4-1-DEG3DEG3-TTP-TX OpenROADM-3-4-DEG3DEG3-TTP-RX - OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3 OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3 + OpenROADM-4-1-DEG3DEG3-TTP-TX + OpenROADM-3-4-DEG3DEG3-TTP-RX + + OpenROADM-3-4-DEG3-to-OpenROADM-4-1-DEG3 + 10 + + fiber46 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3 + OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3 1 ROADM-TO-ROADM - OpenROADM-3-3-DEG3DEG3-TTP-TX OpenROADM-4-2-DEG3DEG3-TTP-RX - OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3 OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3 + OpenROADM-3-3-DEG3DEG3-TTP-TX + OpenROADM-4-2-DEG3DEG3-TTP-RX + + OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3 + 10 + + fiber47 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-2-DEG3-to-OpenROADM-3-3-DEG3 + OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-4-2-DEG3DEG3-TTP-TX OpenROADM-3-3-DEG3DEG3-TTP-RX - OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3 OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3 + OpenROADM-4-2-DEG3DEG3-TTP-TX + OpenROADM-3-3-DEG3DEG3-TTP-RX + + OpenROADM-3-3-DEG3-to-OpenROADM-4-2-DEG3 + 10 + + fiber48 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3 + OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3 1 ROADM-TO-ROADM - OpenROADM-4-4-DEG3DEG3-TTP-TX OpenROADM-5-1-DEG3DEG3-TTP-RX - OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3 OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3 + OpenROADM-4-4-DEG3DEG3-TTP-TX + OpenROADM-5-1-DEG3DEG3-TTP-RX + + OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3 + 10 + + fiber49 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-1-DEG3-to-OpenROADM-4-4-DEG3 + OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-5-1-DEG3DEG3-TTP-TX OpenROADM-4-4-DEG3DEG3-TTP-RX - OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3 OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3 + OpenROADM-5-1-DEG3DEG3-TTP-TX + OpenROADM-4-4-DEG3DEG3-TTP-RX + + OpenROADM-4-4-DEG3-to-OpenROADM-5-1-DEG3 + 10 + + fiber50 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3 + OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3 10 ROADM-TO-ROADM - OpenROADM-4-3-DEG3DEG3-TTP-TX OpenROADM-5-2-DEG3DEG3-TTP-RX - OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3 OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3 + OpenROADM-4-3-DEG3DEG3-TTP-TX + OpenROADM-5-2-DEG3DEG3-TTP-RX + + OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3 + 10 + + fiber51 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-2-DEG3-to-OpenROADM-4-3-DEG3 + OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3 10 ROADM-TO-ROADM - OpenROADM-5-2-DEG3DEG3-TTP-TX OpenROADM-4-3-DEG3DEG3-TTP-RX - OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3 OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3 + OpenROADM-5-2-DEG3DEG3-TTP-TX + OpenROADM-4-3-DEG3DEG3-TTP-RX + + OpenROADM-4-3-DEG3-to-OpenROADM-5-2-DEG3 + 10 + + fiber52 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3 + OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3 1 ROADM-TO-ROADM - OpenROADM-5-4-DEG3DEG3-TTP-TX OpenROADM-1-1-DEG3DEG3-TTP-RX - OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3 OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3 + OpenROADM-5-4-DEG3DEG3-TTP-TX + OpenROADM-1-1-DEG3DEG3-TTP-RX + + OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3 + 10 + + fiber53 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-1-DEG3-to-OpenROADM-5-4-DEG3 + OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-1-1-DEG3DEG3-TTP-TX OpenROADM-5-4-DEG3DEG3-TTP-RX - OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3 OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3 + OpenROADM-1-1-DEG3DEG3-TTP-TX + OpenROADM-5-4-DEG3DEG3-TTP-RX + + OpenROADM-5-4-DEG3-to-OpenROADM-1-1-DEG3 + 10 + + fiber54 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3 + OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3 10 ROADM-TO-ROADM - OpenROADM-5-3-DEG3DEG3-TTP-TX OpenROADM-1-2-DEG3DEG3-TTP-RX - OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3 OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3 + OpenROADM-5-3-DEG3DEG3-TTP-TX + OpenROADM-1-2-DEG3DEG3-TTP-RX + + OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3 + 10 + + fiber55 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-2-DEG3-to-OpenROADM-5-3-DEG3 + OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3 10 ROADM-TO-ROADM - OpenROADM-1-2-DEG3DEG3-TTP-TX OpenROADM-5-3-DEG3DEG3-TTP-RX + OpenROADM-1-2-DEG3DEG3-TTP-TX + OpenROADM-5-3-DEG3DEG3-TTP-RX + + OpenROADM-5-3-DEG3-to-OpenROADM-1-2-DEG3 + 10 + + fiber56 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + diff --git a/tests/sample_configs/NW-simple-topology.xml b/tests/sample_configs/NW-simple-topology.xml index 9252519c8..d007741a0 100644 --- a/tests/sample_configs/NW-simple-topology.xml +++ b/tests/sample_configs/NW-simple-topology.xml @@ -1797,23 +1797,107 @@ OpenROADM-1-2-SRG1SRG1-PP5-TX XPONDER-1-2XPDR-NW5-RX XPONDER-1-2XPDR-NW5-TX-toOpenROADM-1-2-SRG1-SRG1-PP5-RX XPONDER-INPUT - OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 + + OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 + OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-1-1-DEG1DEG1-TTP-TX OpenROADM-1-2-DEG1DEG1-TTP-RX - OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 + OpenROADM-1-1-DEG1DEG1-TTP-TX + OpenROADM-1-2-DEG1DEG1-TTP-RX + + OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 + 10 + + fiber1 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-2-DEG1-to-OpenROADM-1-1-DEG1 + OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-1-2-DEG1DEG1-TTP-TX OpenROADM-1-1-DEG1DEG1-TTP-RX - OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2 OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2 + OpenROADM-1-2-DEG1DEG1-TTP-TX + OpenROADM-1-1-DEG1DEG1-TTP-RX + + OpenROADM-1-1-DEG1-to-OpenROADM-1-2-DEG1 + 10 + + fiber2 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2 + OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-1-2-DEG2DEG2-TTP-TX OpenROADM-1-1-DEG2DEG2-TTP-RX - OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2 OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2 + OpenROADM-1-2-DEG2DEG2-TTP-TX + OpenROADM-1-1-DEG2DEG2-TTP-RX + + OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2 + 10 + + fiber3 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-1-DEG2-to-OpenROADM-1-2-DEG2 + OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-1-1-DEG2DEG2-TTP-TX OpenROADM-1-2-DEG2DEG2-TTP-RX - OpenROADM-2-1-DEG1-DEG1-CTP-TXtoOpenROADM-2-1-DEG2-DEG2-CTP-RX + OpenROADM-1-1-DEG2DEG2-TTP-TX + OpenROADM-1-2-DEG2DEG2-TTP-RX + + OpenROADM-1-2-DEG2-to-OpenROADM-1-1-DEG2 + 10 + + fiber4 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + OpenROADM-2-1-DEG1-DEG1-CTP-TXtoOpenROADM-2-1-DEG2-DEG2-CTP-RX OpenROADM-2-1-DEG1DEG1-CTP-TX OpenROADM-2-1-DEG2DEG2-CTP-RX OpenROADM-2-1-DEG2-DEG2-CTP-TXtoOpenROADM-2-1-DEG1-DEG1-CTP-RX EXPRESS-LINK @@ -1989,22 +2073,106 @@ OpenROADM-2-2-SRG1SRG1-PP5-TX XPONDER-2-2XPDR-NW5-RX XPONDER-2-2XPDR-NW5-TX-toOpenROADM-2-2-SRG1-SRG1-PP5-RX XPONDER-INPUT - OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 + + OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 + OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-2-1-DEG1DEG1-TTP-TX OpenROADM-2-2-DEG1DEG1-TTP-RX - OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 + OpenROADM-2-1-DEG1DEG1-TTP-TX + OpenROADM-2-2-DEG1DEG1-TTP-RX + + OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 + 10 + + fiber5 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-2-DEG1-to-OpenROADM-2-1-DEG1 + OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-2-2-DEG1DEG1-TTP-TX OpenROADM-2-1-DEG1DEG1-TTP-RX - OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2 OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2 + OpenROADM-2-2-DEG1DEG1-TTP-TX + OpenROADM-2-1-DEG1DEG1-TTP-RX + + OpenROADM-2-1-DEG1-to-OpenROADM-2-2-DEG1 + 10 + + fiber6 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2 + OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-2-2-DEG2DEG2-TTP-TX OpenROADM-2-1-DEG2DEG2-TTP-RX - OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2 OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2 + OpenROADM-2-2-DEG2DEG2-TTP-TX + OpenROADM-2-1-DEG2DEG2-TTP-RX + + OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2 + 10 + + fiber7 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-1-DEG2-to-OpenROADM-2-2-DEG2 + OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-2-1-DEG2DEG2-TTP-TX OpenROADM-2-2-DEG2DEG2-TTP-RX + OpenROADM-2-1-DEG2DEG2-TTP-TX + OpenROADM-2-2-DEG2DEG2-TTP-RX + + OpenROADM-2-2-DEG2-to-OpenROADM-2-1-DEG2 + 10 + + fiber8 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + OpenROADM-3-1-DEG1-DEG1-CTP-TXtoOpenROADM-3-1-DEG2-DEG2-CTP-RX OpenROADM-3-1-DEG1DEG1-CTP-TX OpenROADM-3-1-DEG2DEG2-CTP-RX OpenROADM-3-1-DEG2-DEG2-CTP-TXtoOpenROADM-3-1-DEG1-DEG1-CTP-RX @@ -2181,22 +2349,106 @@ OpenROADM-3-2-SRG1SRG1-PP5-TX XPONDER-3-2XPDR-NW5-RX XPONDER-3-2XPDR-NW5-TX-toOpenROADM-3-2-SRG1-SRG1-PP5-RX XPONDER-INPUT - OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 + + OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 + OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-3-1-DEG1DEG1-TTP-TX OpenROADM-3-2-DEG1DEG1-TTP-RX - OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 + OpenROADM-3-1-DEG1DEG1-TTP-TX + OpenROADM-3-2-DEG1DEG1-TTP-RX + + OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 + 10 + + fiber9 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-2-DEG1-to-OpenROADM-3-1-DEG1 + OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-3-2-DEG1DEG1-TTP-TX OpenROADM-3-1-DEG1DEG1-TTP-RX - OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2 OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2 + OpenROADM-3-2-DEG1DEG1-TTP-TX + OpenROADM-3-1-DEG1DEG1-TTP-RX + + OpenROADM-3-1-DEG1-to-OpenROADM-3-2-DEG1 + 10 + + fiber10 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2 + OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-3-2-DEG2DEG2-TTP-TX OpenROADM-3-1-DEG2DEG2-TTP-RX - OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2 OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2 + OpenROADM-3-2-DEG2DEG2-TTP-TX + OpenROADM-3-1-DEG2DEG2-TTP-RX + + OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2 + 10 + + fiber11 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-1-DEG2-to-OpenROADM-3-2-DEG2 + OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-3-1-DEG2DEG2-TTP-TX OpenROADM-3-2-DEG2DEG2-TTP-RX + OpenROADM-3-1-DEG2DEG2-TTP-TX + OpenROADM-3-2-DEG2DEG2-TTP-RX + + OpenROADM-3-2-DEG2-to-OpenROADM-3-1-DEG2 + 10 + + fiber12 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + OpenROADM-4-1-DEG1-DEG1-CTP-TXtoOpenROADM-4-1-DEG2-DEG2-CTP-RX OpenROADM-4-1-DEG1DEG1-CTP-TX OpenROADM-4-1-DEG2DEG2-CTP-RX OpenROADM-4-1-DEG2-DEG2-CTP-TXtoOpenROADM-4-1-DEG1-DEG1-CTP-RX @@ -2373,22 +2625,106 @@ OpenROADM-4-2-SRG1SRG1-PP5-TX XPONDER-4-2XPDR-NW5-RX XPONDER-4-2XPDR-NW5-TX-toOpenROADM-4-2-SRG1-SRG1-PP5-RX XPONDER-INPUT - OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 + + OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 + OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-4-1-DEG1DEG1-TTP-TX OpenROADM-4-2-DEG1DEG1-TTP-RX - OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 + OpenROADM-4-1-DEG1DEG1-TTP-TX + OpenROADM-4-2-DEG1DEG1-TTP-RX + + OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 + 10 + + fiber13 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-2-DEG1-to-OpenROADM-4-1-DEG1 + OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-4-2-DEG1DEG1-TTP-TX OpenROADM-4-1-DEG1DEG1-TTP-RX - OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2 OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2 + OpenROADM-4-2-DEG1DEG1-TTP-TX + OpenROADM-4-1-DEG1DEG1-TTP-RX + + OpenROADM-4-1-DEG1-to-OpenROADM-4-2-DEG1 + 10 + + fiber14 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2 + OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-4-2-DEG2DEG2-TTP-TX OpenROADM-4-1-DEG2DEG2-TTP-RX - OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2 OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2 + OpenROADM-4-2-DEG2DEG2-TTP-TX + OpenROADM-4-1-DEG2DEG2-TTP-RX + + OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2 + 10 + + fiber15 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-1-DEG2-to-OpenROADM-4-2-DEG2 + OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-4-1-DEG2DEG2-TTP-TX OpenROADM-4-2-DEG2DEG2-TTP-RX + OpenROADM-4-1-DEG2DEG2-TTP-TX + OpenROADM-4-2-DEG2DEG2-TTP-RX + + OpenROADM-4-2-DEG2-to-OpenROADM-4-1-DEG2 + 10 + + fiber16 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + OpenROADM-5-1-DEG1-DEG1-CTP-TXtoOpenROADM-5-1-DEG2-DEG2-CTP-RX OpenROADM-5-1-DEG1DEG1-CTP-TX OpenROADM-5-1-DEG2DEG2-CTP-RX OpenROADM-5-1-DEG2-DEG2-CTP-TXtoOpenROADM-5-1-DEG1-DEG1-CTP-RX @@ -2565,60 +2901,354 @@ OpenROADM-5-2-SRG1SRG1-PP5-TX XPONDER-5-2XPDR-NW5-RX XPONDER-5-2XPDR-NW5-TX-toOpenROADM-5-2-SRG1-SRG1-PP5-RX XPONDER-INPUT - OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 + + OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 + OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 1 ROADM-TO-ROADM - OpenROADM-5-1-DEG1DEG1-TTP-TX OpenROADM-5-2-DEG1DEG1-TTP-RX - OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 + OpenROADM-5-1-DEG1DEG1-TTP-TX + OpenROADM-5-2-DEG1DEG1-TTP-RX + + OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 + 10 + + fiber17 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-2-DEG1-to-OpenROADM-5-1-DEG1 + OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 1 ROADM-TO-ROADM - OpenROADM-5-2-DEG1DEG1-TTP-TX OpenROADM-5-1-DEG1DEG1-TTP-RX - OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2 OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2 + OpenROADM-5-2-DEG1DEG1-TTP-TX + OpenROADM-5-1-DEG1DEG1-TTP-RX + + OpenROADM-5-1-DEG1-to-OpenROADM-5-2-DEG1 + 10 + + fiber18 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2 + OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2 1 ROADM-TO-ROADM - OpenROADM-5-2-DEG2DEG2-TTP-TX OpenROADM-5-1-DEG2DEG2-TTP-RX - OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2 OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2 + OpenROADM-5-2-DEG2DEG2-TTP-TX + OpenROADM-5-1-DEG2DEG2-TTP-RX + + OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2 + 10 + + fiber19 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-1-DEG2-to-OpenROADM-5-2-DEG2 + OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2 1 ROADM-TO-ROADM - OpenROADM-5-1-DEG2DEG2-TTP-TX OpenROADM-5-2-DEG2DEG2-TTP-RX - OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3 OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3 + OpenROADM-5-1-DEG2DEG2-TTP-TX + OpenROADM-5-2-DEG2DEG2-TTP-RX + + OpenROADM-5-2-DEG2-to-OpenROADM-5-1-DEG2 + 10 + + fiber20 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3 + OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-1-2-DEG3DEG3-TTP-TX OpenROADM-2-1-DEG3DEG3-TTP-RX - OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3 OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3 + OpenROADM-1-2-DEG3DEG3-TTP-TX + OpenROADM-2-1-DEG3DEG3-TTP-RX + + OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3 + 10 + + fiber21 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-1-DEG3-to-OpenROADM-1-2-DEG3 + OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-2-1-DEG3DEG3-TTP-TX OpenROADM-1-2-DEG3DEG3-TTP-RX - OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3 OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3 + OpenROADM-2-1-DEG3DEG3-TTP-TX + OpenROADM-1-2-DEG3DEG3-TTP-RX + + OpenROADM-1-2-DEG3-to-OpenROADM-2-1-DEG3 + 10 + + fiber22 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3 + OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-2-2-DEG3DEG3-TTP-TX OpenROADM-3-1-DEG3DEG3-TTP-RX - OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3 OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3 + OpenROADM-2-2-DEG3DEG3-TTP-TX + OpenROADM-3-1-DEG3DEG3-TTP-RX + + OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3 + 10 + + fiber23 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-1-DEG3-to-OpenROADM-2-2-DEG3 + OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-3-1-DEG3DEG3-TTP-TX OpenROADM-2-2-DEG3DEG3-TTP-RX - OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3 OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3 + OpenROADM-3-1-DEG3DEG3-TTP-TX + OpenROADM-2-2-DEG3DEG3-TTP-RX + + OpenROADM-2-2-DEG3-to-OpenROADM-3-1-DEG3 + 10 + + fiber24 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3 + OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-3-2-DEG3DEG3-TTP-TX OpenROADM-4-1-DEG3DEG3-TTP-RX - OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3 OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3 + OpenROADM-3-2-DEG3DEG3-TTP-TX + OpenROADM-4-1-DEG3DEG3-TTP-RX + + OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3 + 10 + + fiber25 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-1-DEG3-to-OpenROADM-3-2-DEG3 + OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-4-1-DEG3DEG3-TTP-TX OpenROADM-3-2-DEG3DEG3-TTP-RX - OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3 OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3 + OpenROADM-4-1-DEG3DEG3-TTP-TX + OpenROADM-3-2-DEG3DEG3-TTP-RX + + OpenROADM-3-2-DEG3-to-OpenROADM-4-1-DEG3 + 10 + + fiber26 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3 + OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-4-2-DEG3DEG3-TTP-TX OpenROADM-5-1-DEG3DEG3-TTP-RX - OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3 OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3 + OpenROADM-4-2-DEG3DEG3-TTP-TX + OpenROADM-5-1-DEG3DEG3-TTP-RX + + OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3 + 10 + + fiber27 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-1-DEG3-to-OpenROADM-4-2-DEG3 + OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-5-1-DEG3DEG3-TTP-TX OpenROADM-4-2-DEG3DEG3-TTP-RX - OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3 OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3 + OpenROADM-5-1-DEG3DEG3-TTP-TX + OpenROADM-4-2-DEG3DEG3-TTP-RX + + OpenROADM-4-2-DEG3-to-OpenROADM-5-1-DEG3 + 10 + + fiber28 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3 + OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3 1 ROADM-TO-ROADM - OpenROADM-5-2-DEG3DEG3-TTP-TX OpenROADM-1-1-DEG3DEG3-TTP-RX - OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3 OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3 + OpenROADM-5-2-DEG3DEG3-TTP-TX + OpenROADM-1-1-DEG3DEG3-TTP-RX + + OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3 + 10 + + fiber29 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + + + OpenROADM-1-1-DEG3-to-OpenROADM-5-2-DEG3 + OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3 1 ROADM-TO-ROADM - OpenROADM-1-1-DEG3DEG3-TTP-TX OpenROADM-5-2-DEG3DEG3-TTP-RX + OpenROADM-1-1-DEG3DEG3-TTP-TX + OpenROADM-5-2-DEG3DEG3-TTP-RX + + OpenROADM-5-2-DEG3-to-OpenROADM-1-1-DEG3 + 10 + + fiber30 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + + + diff --git a/tests/sample_configs/honeynode-topo.xml b/tests/sample_configs/honeynode-topo.xml index 93a5922c3..84dba1fd8 100644 --- a/tests/sample_configs/honeynode-topo.xml +++ b/tests/sample_configs/honeynode-topo.xml @@ -130,8 +130,23 @@ ROADMC-DEG2-DEG2-TTP-TXRXtoROADMA-DEG1-DEG1-TTP-TXRX + 10 + + fiber1 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + ROADM-TO-ROADM + 0 ROADMA-SRG1-SRG1-PP1-TXRXtoXPDRA-XPDR1-XPDR1-NETWORK1 @@ -159,8 +174,23 @@ ROADMA-DEG1-DEG1-TTP-TXRXtoROADMC-DEG2-DEG2-TTP-TXRX + 10 + + fiber2 + true + 11.4 + 12 + 12.2 + + 0 + smf + 100000 + 0.5 + + ROADM-TO-ROADM + 0 ROADMC-DEG1-DEG1-CTP-TXRXtoROADMC-SRG1-SRG1-CP-TXRX -- 2.36.6