X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=pce%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fpce%2Fnetworkanalyzer%2FPceLink.java;h=a38682dec36aa124ea4c6a6ea1dbf28374f15b75;hb=bc9a08be9d7cdeb30ecffd3c82ddd656a3a23043;hp=72adcb7f94274a87faac613887f38afeda190bdf;hpb=7c90be243c9c65418b81768e1e0ed6ac58bad4a8;p=transportpce.git diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java index 72adcb7f9..a38682dec 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java @@ -8,55 +8,71 @@ package org.opendaylight.transportpce.pce.networkanalyzer; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; import java.util.List; - -import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.transportpce.pce.constraints.PceConstraints; +import java.util.Map; import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev181130.span.attributes.LinkConcatenation; +import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev181130.span.attributes.LinkConcatenation.FiberType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev181130.span.attributes.LinkConcatenationKey; 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.http.transportpce.topology.rev200129.OtnLinkType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PceLink { +@SuppressWarnings("serial") +@edu.umd.cs.findbugs.annotations.SuppressFBWarnings( + value = "SE_NO_SERIALVERSIONID", + justification = "https://github.com/rzwitserloot/lombok/wiki/WHY-NOT:-serialVersionUID") +public class PceLink implements Serializable { /* Logging. */ private static final Logger LOG = LoggerFactory.getLogger(PceLink.class); - ///////////////////////// LINKS //////////////////// /* * extension of Link to include constraints and Graph weight */ - double weight = 0; - private boolean isValid = true; // this member is for XPONDER INPUT/OUTPUT links. - // it keeps name of client correcponding to NETWORK TP + // it keeps name of client corresponding to NETWORK TP private String client = ""; - private final LinkId linkId; private final OpenroadmLinkType linkType; private final NodeId sourceId; private final NodeId destId; - private final Object sourceTP; - private final Object destTP; - private final String sourceSupNodeId; - private final String destSupNodeId; + private transient Object sourceTP; + private transient Object destTP; + private final String sourceNetworkSupNodeId; + private final String destNetworkSupNodeId; private final String sourceCLLI; private final String destCLLI; private final LinkId oppositeLink; private final Long latency; + private final Long availableBandwidth; + private final Long usedBandwidth; private final List srlgList; private final double osnr; - private final Span omsAttributesSpan; + private final transient Span omsAttributesSpan; + //meter per ms + private static final double CELERITY = 2.99792458 * 1e5; + private static final double NOISE_MASK_A = 0.571429; + private static final double NOISE_MASK_B = 39.285714; + private static final double UPPER_BOUND_OSNR = 33; + private static final double LOWER_BOUND_OSNR = 0.1; public PceLink(Link link, PceNode source, PceNode dest) { - LOG.debug("PceLink: : PceLink start "); + LOG.info("PceLink: : PceLink start "); this.linkId = link.getLinkId(); @@ -66,56 +82,44 @@ public class PceLink { this.sourceTP = link.getSource().getSourceTp(); this.destTP = link.getDestination().getDestTp(); - this.sourceSupNodeId = source.getSupNodeIdPceNode(); - this.destSupNodeId = dest.getSupNodeIdPceNode(); + this.sourceNetworkSupNodeId = source.getSupNetworkNodeId(); + this.destNetworkSupNodeId = dest.getSupNetworkNodeId(); - this.sourceCLLI = source.getCLLI(); - this.destCLLI = dest.getCLLI(); + this.sourceCLLI = source.getSupClliNodeId(); + this.destCLLI = dest.getSupClliNodeId(); this.linkType = MapUtils.calcType(link); this.oppositeLink = calcOpposite(link); - this.latency = calcLatency(link); if (this.linkType == OpenroadmLinkType.ROADMTOROADM) { this.omsAttributesSpan = MapUtils.getOmsAttributesSpan(link); this.srlgList = MapUtils.getSRLG(link); - this.osnr = retrieveOSNR(); + this.latency = calcLatency(link); + this.osnr = calcSpanOSNR(); + this.availableBandwidth = 0L; + this.usedBandwidth = 0L; + } else if (this.linkType == OpenroadmLinkType.OTNLINK) { + this.availableBandwidth = MapUtils.getAvailableBandwidth(link); + this.usedBandwidth = MapUtils.getUsedBandwidth(link); + this.srlgList = MapUtils.getSRLGfromLink(link); + this.osnr = 0.0; + this.latency = 0L; + this.omsAttributesSpan = null; } else { this.omsAttributesSpan = null; 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 tmplinkType = null; - - // ID and type - link1 = link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130 - .Link1.class); - if (link1 == null) { - this.isValid = false; - LOG.error("PceLink: No Link augmentation available. Link is ignored {}", this.linkId); - return null; + this.latency = 0L; + //infinite OSNR in DB + this.osnr = 100L; + this.availableBandwidth = 0L; + this.usedBandwidth = 0L; } - - tmplinkType = link1.getLinkType(); - if (tmplinkType == null) { - this.isValid = false; - LOG.error("PceLink: No Link type available. Link is ignored {}", this.linkId); - return null; - } - return tmplinkType; + LOG.debug("PceLink: created PceLink {}", linkId); } + //Retrieve the opposite link private LinkId calcOpposite(Link link) { - // opposite link - LinkId tmpoppositeLink = MapUtils.extractOppositeLink(link); if (tmpoppositeLink == null) { LOG.error("PceLink: Error calcOpposite. Link is ignored {}", link.getLinkId().getValue()); @@ -124,98 +128,82 @@ public class PceLink { return tmpoppositeLink; } + //Compute the link latency : if the latency is not defined, the latency is computed from the omsAttributesSpan private Long calcLatency(Link link) { - Long tmplatency = 1L; - Link1 link1 = null; - // latency - link1 = link.augmentation(Link1.class); - try { - tmplatency = link1.getLinkLatency(); - } catch (NullPointerException e) { - LOG.debug("the latency does not exist for this link"); + Link1 link1 = link.augmentation(Link1.class); + if (link1.getLinkLatency() != null) { + return link1.getLinkLatency().toJava(); + } + if (this.omsAttributesSpan == null) { + return 1L; } - return tmplatency; + double tmp = 0; + Map linkConcatenationMap = this.omsAttributesSpan + .nonnullLinkConcatenation(); + for (Map.Entry entry : linkConcatenationMap.entrySet()) { + // Length is expressed in meter and latency is expressed in ms according to OpenROADM MSA + if (entry == null || entry.getValue() == null || entry.getValue().getSRLGLength() == null) { + LOG.debug("In PceLink: cannot compute the latency for the link {}", link.getLinkId().getValue()); + return 1L; + } + tmp += entry.getValue().getSRLGLength().toJava() / CELERITY; + LOG.info("In PceLink: The latency of link {} == {}", link.getLinkId(), tmp); + } + return (long) Math.ceil(tmp); } - @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance") - public double retrieveOSNR() { - // sum of 1 over the span OSNRs (linear units) - double sum = 0; - // link OSNR, in dB - double linkOsnrDb; - // link OSNR, in dB - double linkOsnrLu; - // span OSNR, in dB - double spanOsnrDb; - // span OSNR, in linear units - double spanOsnrLu; - // default amplifier noise value, in dB - double ampNoise = 5.5; - // fiber span measured loss, in dB - double loss; - // launch power, in dB - double power; - double constantA = 38.97293; - double constantB = 0.72782; - double constantC = -0.532331; - double constactD = -0.019549; - double upperBoundosnr = 33; - double lowerBoundosnr = 0.1; - - if (omsAttributesSpan == null) { - // indicates no data or N/A + //Compute the OSNR of a span + public double calcSpanOSNR() { + if (this.omsAttributesSpan == null) { return 0L; } - loss = omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue(); - switch (omsAttributesSpan.getLinkConcatenation().get(0).getFiberType()) { + Collection linkConcatenationList = + this.omsAttributesSpan.nonnullLinkConcatenation().values(); + if (linkConcatenationList == null) { + LOG.error("in PceLink : Null field in the OmsAttrubtesSpan"); + return 0L; + } + Iterator linkConcatenationiterator = linkConcatenationList.iterator(); + if (!linkConcatenationiterator.hasNext()) { + return 0L; + } + // power on the output of the previous ROADM (dBm) + double pout = retrievePower(linkConcatenationiterator.next().getFiberType()); + // span loss (dB) + double spanLoss = this.omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue(); + // power on the input of the current ROADM (dBm) + double pin = pout - spanLoss; + double spanOsnrDb = NOISE_MASK_A * pin + NOISE_MASK_B; + if (spanOsnrDb > UPPER_BOUND_OSNR) { + spanOsnrDb = UPPER_BOUND_OSNR; + } else if (spanOsnrDb < LOWER_BOUND_OSNR) { + spanOsnrDb = LOWER_BOUND_OSNR; + } + return spanOsnrDb; + } + + private double retrievePower(FiberType fiberType) { + double power; + switch (fiberType) { case Smf: power = 2; break; - case Eleaf: power = 1; break; - - case Oleaf: - power = 0; - break; - - case Dsf: - power = 0; - break; - - case Truewave: - power = 0; - break; - case Truewavec: power = -1; break; - + case Oleaf: + case Dsf: + case Truewave: case NzDsf: - power = 0; - break; - case Ull: - power = 0; - break; - default: power = 0; break; } - spanOsnrDb = constantA + constantB * power + constantC * loss + constactD * power * loss; - 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; - //link_osnr_dB = 10 * Math.log10(1 / sum); - LOG.debug("In retrieveosnr: link osnr is {} dB", linkOsnrLu); - return linkOsnrLu; + return power; } public LinkId getOppositeLink() { @@ -259,12 +247,20 @@ public class PceLink { return latency.doubleValue(); } - public String getsourceSupNodeId() { - return sourceSupNodeId; + public Long getAvailableBandwidth() { + return availableBandwidth; + } + + public Long getUsedBandwidth() { + return usedBandwidth; } - public String getdestSupNodeId() { - return destSupNodeId; + public String getsourceNetworkSupNodeId() { + return sourceNetworkSupNodeId; + } + + public String getdestNetworkSupNodeId() { + return destNetworkSupNodeId; } public List getsrlgList() { @@ -284,25 +280,11 @@ public class PceLink { } public boolean isValid() { - if ((this.linkId == null) || (this.linkType == null) - || (this.oppositeLink == null)) { + 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)) { - isValid = false; - LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", linkId); - } - 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); - } + isValid = checkParams(); if ((this.omsAttributesSpan == null) && (this.linkType == OpenroadmLinkType.ROADMTOROADM)) { isValid = false; LOG.error("PceLink: Error reading Span for OMS link. Link is ignored {}", linkId); @@ -314,8 +296,100 @@ public class PceLink { return isValid; } + public boolean isOtnValid(Link link, String serviceType) { + + if (this.linkType != OpenroadmLinkType.OTNLINK) { + LOG.error("PceLink: Not an OTN link. Link is ignored {}", linkId); + return false; + } + + OtnLinkType otnLinkType = link + .augmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class) + .getOtnLinkType(); + if (this.availableBandwidth == 0L) { + LOG.error("PceLink: No bandwidth available for OTN Link, link {} is ignored ", linkId); + return false; + } + + long neededBW; + OtnLinkType neededType = null; + switch (serviceType) { + + case "ODU4": + if (this.usedBandwidth != 0L) { + return false; + } + neededBW = 100000L; + neededType = OtnLinkType.OTU4; + break; + case "ODU2": + case "ODU2e": + neededBW = 12500L; + break; + case "ODU0": + neededBW = 1250L; + break; + case "ODU1": + neededBW = 2500L; + break; + case "10GE": + neededBW = 10000L; + neededType = OtnLinkType.ODTU4; + break; + case "1GE": + neededBW = 1000L; + neededType = OtnLinkType.ODTU4; + break; + default: + LOG.error("PceLink: isOtnValid Link {} unsupported serviceType {} ", linkId, serviceType); + return false; + } + + if ((this.availableBandwidth >= neededBW) + && ((neededType == null) || (neededType.equals(otnLinkType)))) { + LOG.info("PceLink: Selected Link {} has available bandwidth and is eligible for {} creation ", + linkId, serviceType); + } + + return checkParams(); + } + + private boolean checkParams() { + if ((this.linkId == null) || (this.linkType == null) || (this.oppositeLink == null)) { + LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", linkId); + return false; + } + if ((this.sourceId == null) || (this.destId == null) || (this.sourceTP == null) || (this.destTP == null)) { + LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", linkId); + return false; + } + if ((this.sourceNetworkSupNodeId.equals("")) || (this.destNetworkSupNodeId.equals(""))) { + LOG.error("PceLink: No Link source SuppNodeID or destination SuppNodeID is available. Link is ignored {}", + linkId); + return false; + } + if ((this.sourceCLLI.equals("")) || (this.destCLLI.equals(""))) { + LOG.error("PceLink: No Link source CLLI or destination CLLI is available. Link is ignored {}", linkId); + return false; + } + + return true; + } + + @Override public String toString() { - return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latecy=" + latency; + return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latency=" + latency; } + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + out.writeObject(this.sourceTP); + out.writeObject(this.destTP); + } + + private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException { + in.defaultReadObject(); + this.sourceTP = in.readObject(); + this.destTP = in.readObject(); + } }