new PceCalculation(input, networkTransaction, hardConstraints, softConstraints, rc);
nwAnalizer.retrievePceNetwork();
rc = nwAnalizer.getReturnStructure();
+ String serviceType = nwAnalizer.getServiceType();
if (!rc.getStatus()) {
LOG.error("In pathComputationWithConstraints, nwAnalizer: result = {}", rc.toString());
return;
}
LOG.info("PceGraph ...");
PceGraph graph = new PceGraph(nwAnalizer.getaendPceNode(),
- nwAnalizer.getzendPceNode(), nwAnalizer.getAllPceNodes(),
- hardConstraints, softConstraints, rc);
+ nwAnalizer.getzendPceNode(), nwAnalizer.getAllPceNodes(),
+ pceHardConstraints, pceSoftConstraints, rc, serviceType);
graph.calcPath();
rc = graph.getReturnStructure();
if (!rc.getStatus()) {
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.PathValidator;
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.topology.rev180226.networks.network.Link;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return true;
}
+}
-}
\ No newline at end of file
private Map<NodeId, PceNode> allPceNodes = new HashMap<NodeId, PceNode>();
private PceNode apceNode = null;
private PceNode zpceNode = null;
+ private String serviceType = "";
PceConstraints pceHardConstraints;
PceConstraints pceSoftConstraints;
private List<PceLink> pathAtoZ = new ArrayList<PceLink>();
public PceGraph(PceNode aendNode, PceNode zendNode, Map<NodeId, PceNode> allPceNodes,
- PceConstraints pceHardConstraints, PceConstraints pceSoftConstraints, PceResult pceResult) {
+ PceConstraints pceHardConstraints, PceConstraints pceSoftConstraints, PceResult pceResult,
+ String serviceType) {
super();
this.apceNode = aendNode;
this.zpceNode = zendNode;
this.pceResult = pceResult;
this.pceHardConstraints = pceHardConstraints;
this.pceSoftConstraints = pceSoftConstraints;
+ this.serviceType = serviceType;
LOG.info("In GraphCalculator: A and Z = {} / {} ", aendNode.toString(), zendNode.toString());
LOG.debug("In GraphCalculator: allPceNodes size {}, nodes {} ", allPceNodes.size(), allPceNodes.toString());
pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
for (GraphPath<String, PceGraphEdge> path : allWPaths) {
PostAlgoPathValidator papv = new PostAlgoPathValidator();
- pceResult = papv.checkPath(path, allPceNodes, pceResult, pceHardConstraints);
+ pceResult = papv.checkPath(path, allPceNodes, pceResult, pceHardConstraints, serviceType);
LOG.info("In calcPath after PostAlgoPathValidator {} {}",
pceResult.getResponseCode(), ResponseCodes.RESPONSE_OK);
}
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;
+ if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
+ LOG.info("In calcPath Path FOUND path for wl [{}], hops {}, distance per metrics {}, path AtoZ {}",
+ pceResult.getResultWavelength(), pathAtoZ.size(), path.getWeight(), pathAtoZ.toString());
+ break;
+ } else {
+ // Service is at OTN layer and is relying on a supporting wavelength service
+ LOG.info("In calcPath Path FOUND path for hops {}, distance per metrics {}, path AtoZ {}",
+ pathAtoZ.size(), path.getWeight(), pathAtoZ.toString());
+ break;
+ }
+
}
if (shortestPathAtoZ != null) {
case PropagationDelay :
weight = link.getLatency();
LOG.debug("In PceGraph PropagationDelay is used as a metrics. {}", link.toString());
+ if ((("1GE".equals(serviceType)) || ("10GE".equals(serviceType)) || ("ODU4".equals(serviceType)))
+ && (weight == 0)) {
+ LOG.warn("PropagationDelay set as metric, but latency is null: is latency set for OTN link {}?",
+ link.toString());
+ }
break;
default:
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.transportpce.pce.networkanalyzer.PceOtnNode;
import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
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.NodeId;
public static final Long CONST_OSNR = 1L;
public static final double SYS_MARGIN = 0;
- public PceResult checkPath(GraphPath<String, PceGraphEdge> path,
- Map<NodeId, PceNode> allPceNodes, PceResult pceResult, PceConstraints pceHardConstraints) {
+ public PceResult checkPath(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes,
+ PceResult pceResult, PceConstraints pceHardConstraints, String serviceType) {
- //check if the path is empty
+ // check if the path is empty
if (path.getEdgeList().size() == 0) {
pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
return pceResult;
}
+ if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
+ // choose wavelength available in all nodes of the path
+ Long waveL = chooseWavelength(path, allPceNodes);
+ if (waveL < 0) {
+ pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+ pceResult.setLocalCause(PceResult.LocalCause.NO_PATH_EXISTS);
+ return pceResult;
+ }
+ pceResult.setResultWavelength(waveL);
+ LOG.info("In PostAlgoPathValidator: chooseWavelength WL found {} {}", waveL, path.toString());
- //Choose wavelength available in all nodes of the path
- Long waveL = chooseWavelength(path, allPceNodes);
- if (waveL < 0) {
- pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
- pceResult.setLocalCause(PceResult.LocalCause.NO_PATH_EXISTS);
- return pceResult;
- }
- pceResult.setResultWavelength(waveL);
- 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
- // TODO here other post algo validations can be added
- // more data can be sent to PceGraph module via PceResult structure if required
+ // Check the OSNR
+ if (!checkOSNR(path)) {
+ pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+ pceResult.setLocalCause(PceResult.LocalCause.OUT_OF_SPEC_OSNR);
+ return pceResult;
+ }
- //Check the OSNR
- if (!checkOSNR(path)) {
- pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
- pceResult.setLocalCause(PceResult.LocalCause.OUT_OF_SPEC_OSNR);
- return pceResult;
- }
+ // Check if MaxLatency is defined in the hard constraints
+ if (pceHardConstraints.getMaxLatency() != -1) {
+ if (!checkLatency(pceHardConstraints.getMaxLatency(), path)) {
+ pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+ pceResult.setLocalCause(PceResult.LocalCause.TOO_HIGH_LATENCY);
+ return pceResult;
+ }
+ }
- //Check if MaxLatency is defined in the hard constraints
- if (pceHardConstraints.getMaxLatency() != -1) {
- if (!checkLatency(pceHardConstraints.getMaxLatency(), path)) {
+ // Check if nodes are included in the hard constraints
+ if (!checkInclude(path, pceHardConstraints)) {
pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
- pceResult.setLocalCause(PceResult.LocalCause.TOO_HIGH_LATENCY);
+ pceResult.setLocalCause(PceResult.LocalCause.HD_NODE_INCLUDE);
return pceResult;
}
- }
+ pceResult.setRC(ResponseCodes.RESPONSE_OK);
- //Check if nodes are included in the hard constraints
- if (!checkInclude(path, pceHardConstraints)) {
+ } else if (("1GE".equals(serviceType)) || ("10GE".equals(serviceType))) {
+ // Path is at the OTN layer
pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
- pceResult.setLocalCause(PceResult.LocalCause.HD_NODE_INCLUDE);
- return pceResult;
+ // In a first step we select the first tribPort available on the first edge
+ // TODO : after the way to pass trib-ports and trib-slots to the renderer has
+ // been adapted to fit
+ // with multiple OTN Hops, each first available port shall be passed for each
+ // edge to Renderer
+ Integer tribPort = chooseTribPort(path, allPceNodes).get(0).get(0);
+ // TODO : Same comment apply for tribSlot
+ Integer tribSlot = chooseTribSlot(path, allPceNodes).get(0).get(0);
+
+ if (tribPort != null) {
+ // Temporarily we use wavelength-number to provide the TribPort
+ // TODO adapt the path-description
+ // TODO make the adaptation to return the first tribSlot in an intermediate
+ // phase
+ pceResult.setResultWavelength(tribPort);
+ pceResult.setRC(ResponseCodes.RESPONSE_OK);
+ LOG.info("In PostAlgoPathValidator: chooseTribPort TribPort found {} {}", tribPort, path.toString());
+ }
}
-
- pceResult.setRC(ResponseCodes.RESPONSE_OK);
return pceResult;
}
- //Choose the first available wavelength from the source to the destination
+ // Choose the first available wavelength from the source to the destination
private Long chooseWavelength(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
Long wavelength = -1L;
return wavelength;
}
- //Check the latency
+ // Check the latency
private boolean checkLatency(Long maxLatency, GraphPath<String, PceGraphEdge> path) {
double latency = 0;
for (PceGraphEdge edge : path.getEdgeList()) {
try {
latency += edge.link().getLatency();
- LOG.debug("- In checkLatency: latency of {} = {} units", edge.link().getLinkId().getValue(),latency);
+ LOG.debug("- In checkLatency: latency of {} = {} units", edge.link().getLinkId().getValue(), latency);
} catch (NullPointerException e) {
LOG.warn("- In checkLatency: the link {} does not contain latency field",
edge.link().getLinkId().getValue());
return true;
}
- //Check the inclusion if it is defined in the hard constraints
+ // Check the inclusion if it is defined in the hard constraints
private boolean checkInclude(GraphPath<String, PceGraphEdge> path, PceConstraints pceHardConstraintsInput) {
List<ResourcePair> listToInclude = pceHardConstraintsInput.getListToInclude();
if (listToInclude.isEmpty()) {
PceConstraints pceHardConstraints) {
List<String> listOfElements = new ArrayList<String>();
- for (PceGraphEdge link: pathEdges) {
+ for (PceGraphEdge link : pathEdges) {
switch (type) {
case NODE:
listOfElements.add(link.link().getdestSupNodeId());
break;
}
- // srlg of link is List<Long>. But in this algo we need string representation of one SRLG
- // this should be any SRLG mentioned in include constraints if any of them if mentioned
+ // srlg of link is List<Long>. But in this algo we need string representation of
+ // one SRLG
+ // this should be any SRLG mentioned in include constraints if any of them if
+ // mentioned
boolean found = false;
for (Long srlg : link.link().getsrlgList()) {
String srlgStr = String.valueOf(srlg);
if (pceHardConstraints.getSRLGnames().contains(srlgStr)) {
listOfElements.add(srlgStr);
- LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link().toString());
+ LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link());
found = true;
continue;
}
return listOfElements;
}
- //Check the path OSNR
+ private List<List<Integer>> chooseTribPort(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
+ List<List<Integer>> tribPort = new ArrayList<>();
+ boolean statusOK = true;
+ boolean check = false;
+ Object nodeClass = allPceNodes.getClass();
+ if (nodeClass.getClass().isInstance(PceNode.class)) {
+ LOG.debug("In choosetribPort: AllPceNodes contains PceNode instance, no trib port search");
+ return tribPort;
+ } else if (nodeClass.getClass().isInstance(PceOtnNode.class)) {
+ LOG.debug("In choosetribPort: {} {}", path.getLength(), path.toString());
+ for (PceGraphEdge edge : path.getEdgeList()) {
+ LOG.debug("In chooseTribPort: source {} ", edge.link().getSourceId().toString());
+ PceNode pceNode = allPceNodes.get(edge.link().getSourceId());
+ Object tps = allPceNodes.get(edge.link().getSourceTP());
+ Object tpd = allPceNodes.get(edge.link().getDestTP());
+ if ((pceNode.getAvailableTribPorts().containsKey(tps.toString()))
+ && (pceNode.getAvailableTribPorts().containsKey(tpd.toString()))) {
+
+ List<Integer> tribPortEdgeSourceN = new ArrayList<>();
+ List<Integer> tribPortEdgeDestN = new ArrayList<>();
+ tribPortEdgeSourceN = pceNode.getAvailableTribPorts().get(tps.toString());
+ tribPortEdgeDestN = pceNode.getAvailableTribPorts().get(tps.toString());
+ check = false;
+ for (int i = 0; i <= 9; i++) {
+ if (tribPortEdgeSourceN.get(i) == null) {
+ break;
+ }
+ if (tribPortEdgeSourceN.get(i) == tribPortEdgeDestN.get(i)) {
+ check = true;
+ } else {
+ check = false;
+ LOG.debug("In chooseTribPort: Misalignement of trib port between source {} and dest {}",
+ edge.link().getSourceId().toString(), edge.link().getDestId().toString());
+ break;
+ }
+ }
+ if (check) {
+ tribPort.add(tribPortEdgeSourceN);
+ }
+ } else {
+ LOG.debug("In chooseTribPort: source {} does not have provisonned hosting HO interface ",
+ edge.link().getSourceId().toString());
+ statusOK = false;
+ }
+ }
+ }
+ if (statusOK && check) {
+ return tribPort;
+ } else {
+ tribPort.clear();
+ return tribPort;
+ }
+
+ }
+
+ private List<List<Integer>> chooseTribSlot(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
+ List<List<Integer>> tribSlot = new ArrayList<>();
+ boolean statusOK = true;
+ boolean check = false;
+ Object nodeClass = allPceNodes.getClass();
+ if (nodeClass.getClass().isInstance(PceNode.class)) {
+ LOG.debug("In choosetribSlot: AllPceNodes contains PceNode instance, no trib port search");
+ return tribSlot;
+ } else if (nodeClass.getClass().isInstance(PceOtnNode.class)) {
+ LOG.debug("In choosetribPort: {} {}", path.getLength(), path.toString());
+ for (PceGraphEdge edge : path.getEdgeList()) {
+ LOG.debug("In chooseTribSlot: source {} ", edge.link().getSourceId().toString());
+ PceNode pceNode = allPceNodes.get(edge.link().getSourceId());
+ Object tps = allPceNodes.get(edge.link().getSourceTP());
+ Object tpd = allPceNodes.get(edge.link().getDestTP());
+ if ((pceNode.getAvailableTribSlots().containsKey(tps.toString()))
+ && (pceNode.getAvailableTribSlots().containsKey(tpd.toString()))) {
+
+ List<Integer> tribSlotEdgeSourceN = new ArrayList<>();
+ List<Integer> tribSlotEdgeDestN = new ArrayList<>();
+ tribSlotEdgeSourceN = pceNode.getAvailableTribSlots().get(tps.toString());
+ tribSlotEdgeDestN = pceNode.getAvailableTribSlots().get(tps.toString());
+ check = false;
+ for (int i = 0; i <= 79; i++) {
+ if (tribSlotEdgeSourceN.get(i) == null) {
+ break;
+ }
+ // TODO This will need to be modified as soon as the trib-slots allocation per
+ // trib-port
+ // policy applied by the different manufacturer is known
+ if (tribSlotEdgeSourceN.get(i) == tribSlotEdgeDestN.get(i)) {
+ check = true;
+ } else {
+ check = false;
+ LOG.debug("In chooseTribSlot: Misalignement of trib slots between source {} and dest {}",
+ edge.link().getSourceId().toString(), edge.link().getDestId().toString());
+ break;
+ }
+ }
+ if (check) {
+ tribSlot.add(tribSlotEdgeSourceN);
+ }
+ } else {
+ LOG.debug("In chooseTribSlot: source {} does not have provisonned hosting HO interface ",
+ edge.link().getSourceId().toString());
+ statusOK = false;
+ }
+ }
+ }
+ if (statusOK && check) {
+ return tribSlot;
+ } else {
+ tribSlot.clear();
+ return tribSlot;
+ }
+
+ }
+
+ // Check the path OSNR
private boolean checkOSNR(GraphPath<String, PceGraphEdge> path) {
double linkOsnrDb;
double osnrDb = 0;
}
try {
osnrDb = getOsnrDb(1 / inverseLocalOsnr);
- }
- catch (ArithmeticException e) {
+ } catch (ArithmeticException e) {
LOG.debug("In checkOSNR: OSNR is equal to 0 and the number of links is: {}", path.getEdgeList().size());
return false;
}
if ((osnrDb + SYS_MARGIN) < MIN_OSNR_W100G) {
return false;
}
+ double localOsnr = 0L;
+ LOG.info("In OSNR Stub: {}", localOsnr);
+ // TODO : change this to return OSNR value and validate or invalidate the path
return true;
}
return (CONST_OSNR / linkOsnrLu);
}
-}
\ No newline at end of file
+}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.TreeMap;
import org.opendaylight.transportpce.common.NetworkUtils;
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.link.rev181130.span.attributes.LinkConcatenation;
-
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;
return srlgList;
}
+ public static List<Long> getSRLGfromLink(Link link) {
+ List<Long> srlgList = new ArrayList<Long>();
+ org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1 linkC =
+ link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class);
+ if (linkC == null) {
+ LOG.error("MapUtils: No Link augmentation available. {}", link.getLinkId().getValue());
+
+ } else {
+ try {
+ List<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.networks.network.link
+ .LinkConcatenation> linkConcatenation = linkC.getLinkConcatenation();
+
+
+ for (org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.networks.network.link
+ .LinkConcatenation lc : linkConcatenation) {
+ srlgList.add(lc.getSRLGId());
+ }
+ } catch (NullPointerException e) {
+ LOG.debug("No concatenation for this link");
+ }
+ }
+ return srlgList;
+ }
+
public static String getSupNode(Node node) {
List<SupportingNode> supNodes = node.getSupportingNode();
for (SupportingNode snode : supNodes) {
return null;
}
+ public static TreeMap<String, String> getAllSupNode(Node node) {
+ TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
+ List<SupportingNode> supNodes = new ArrayList<SupportingNode>();
+ try {
+ supNodes = node.getSupportingNode();
+ } catch (NullPointerException e) {
+ LOG.debug("No Supporting Node for the node {}", node);
+ }
+ for (SupportingNode supnode :supNodes) {
+ allSupNodes.put(supnode.getNetworkRef().getValue(),
+ supnode.getNodeRef().getValue());
+ }
+ return allSupNodes;
+ }
+
+ public static String getSupLink(Link link) {
+ String supLink = "";
+ try {
+ supLink = link.getSupportingLink().get(0).getLinkRef().toString();
+ } catch (NullPointerException e) {
+ LOG.debug("No Supporting Link for the link {}", link);
+ }
+ return supLink;
+ }
+
+
+ public static Long getAvailableBandwidth(Link link) {
+ Link1 link1 = null;
+ Long availableBW = 0L;
+ // ID and type
+ link1 = link.augmentation(Link1.class);
+ if (link1 == null) {
+ LOG.error("MapUtils: No Link augmentation available. {}", link.getLinkId().getValue());
+ return availableBW;
+ } else {
+ OpenroadmLinkType tmplType = null;
+ tmplType = link1.getLinkType();
+ if (tmplType == null) {
+ LOG.error("MapUtils: No Link type available. {}", link.getLinkId().getValue());
+ return null;
+ } else if (tmplType == OpenroadmLinkType.OTNLINK) {
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1 link11 =
+ link.augmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1.class);
+ if (link11 == null) {
+ LOG.error("MapUtils: No Link augmentation available for {}", link.getLinkId().getValue());
+ return availableBW;
+ } else {
+ availableBW = link11.getAvailableBandwidth();
+ return availableBW;
+ }
+
+ } else {
+ LOG.error("MapUtils: Evaluated Link is not of OTN Type");
+ }
+ }
+
+
+ return 0L;
+ }
+
public static OpenroadmLinkType calcType(Link link) {
Link1 link1 = null;
OpenroadmLinkType tmplType = null;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+//import org.opendaylight.yangtools.yang.common.Decimal64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private PathComputationRequestInput input;
private String anodeId = "";
private String znodeId = "";
+ private String serviceFormatA = "";
+ private String serviceFormatZ = "";
+ private String serviceType = "";
+ private Long serviceRate = 0L;
private PceConstraints pceHardConstraints;
private boolean parseInput() {
anodeId = input.getServiceAEnd().getNodeId();
znodeId = input.getServiceZEnd().getNodeId();
+ serviceFormatA = input.getServiceAEnd().getServiceFormat().getName();
+ serviceFormatZ = input.getServiceZEnd().getServiceFormat().getName();
+ serviceRate = input.getServiceAEnd().getServiceRate();
+
LOG.info("parseInput: A and Z :[{}] and [{}]", anodeId, znodeId);
+ if (!(serviceFormatA.equals(serviceFormatZ))) {
+ LOG.info("parseInput: different service format for A and Z not handled, will use service format from Aend");
+ } else if (serviceRate == 100L) {
+ switch (serviceFormatA) {
+ case "Ethernet":
+ case "OC":
+ serviceType = "100GE";
+ break;
+ case "OTU":
+ serviceType = "OTU4";
+ break;
+ case "ODU":
+ serviceType = "ODU4";
+ break;
+ default:
+ LOG.debug("parseInput: unsupported service type: Format {} Rate 100L", serviceFormatA);
+ break;
+ }
+ //switch(serviceRate) may seem a better option at first glance.
+ //But switching on Long or long is not directly possible in Java.
+ //And casting to int bumps the limit here.
+ //Passing by ENUM or String are possible alternatives.
+ //Maybe HashMap and similar options should also be considered here.
+ } else if (serviceFormatA == "Ethernet") {
+ //only rate 100L is currently supported except in Ethernet
+ if (serviceRate == 10L) {
+ serviceType = "10GE";
+ } else if (serviceRate == 1L) {
+ serviceType = "1GE";
+ } else {
+ LOG.debug("parseInput: unsupported service type: Format Ethernet Rate {}", String.valueOf(serviceRate));
+ }
+ } else {
+ LOG.debug("parseInput: unsupported service type: Format {} Rate {}",
+ serviceFormatA, String.valueOf(serviceRate));
+ }
+
returnStructure.setRate(input.getServiceAEnd().getServiceRate());
+ returnStructure.setServiceFormat(input.getServiceAEnd().getServiceFormat());
return true;
}
private boolean readMdSal() {
- LOG.info("readMdSal: network {}", NetworkUtils.OVERLAY_NETWORK_ID);
- InstanceIdentifier<Network> nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
- .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).build();
+ InstanceIdentifier<Network> nwInstanceIdentifier = null;
Network nw = null;
+ if (("OC".equals(serviceFormatA)) || ("OTU".equals(serviceFormatA)) || (("Ethernet".equals(serviceFormatA))
+ && (serviceRate == 100L))) {
+
+ LOG.info("readMdSal: network {}", NetworkUtils.OVERLAY_NETWORK_ID);
+ nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
+ .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).build();
+ } else if ("ODU".equals(serviceFormatA)) {
+ LOG.info("readMdSal: network {}", NetworkUtils.OTN_NETWORK_ID);
+ nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
+ .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))).build();
+ } else {
+ LOG.info("readMdSal: service-rate {} / service-format not handled {}", serviceRate, serviceFormatA);
+ return false;
+ }
+
try {
Optional<Network> nwOptional =
networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier).get();
networkTransactionService.close();
returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
throw new RuntimeException(
- "readMdSal: Error reading from operational store, topology : " + nwInstanceIdentifier + " :" + e);
+ "readMdSal: Error reading from operational store, topology : " + nwInstanceIdentifier + " :" + e);
}
networkTransactionService.close();
LOG.debug("analyzeNw: allNodes size {}, allLinks size {}", allNodes.size(), allLinks.size());
- for (Node node : allNodes) {
- validateNode(node);
- }
- 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;
- }
+ if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
+ // 100GE service and OTU4 service are handled at the openroadm-topology layer
+ for (Node node : allNodes) {
+ validateNode(node);
+ }
- for (Link link : allLinks) {
- validateLink(link);
- }
+ LOG.debug("analyzeNw: allPceNodes size {}", allPceNodes.size());
- LOG.debug("analyzeNw: addLinks size {}, dropLinks size {}", addLinks.size(), dropLinks.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 : allLinks) {
+ validateLink(link);
+ }
+ // debug prints
+ LOG.debug("analyzeNw: addLinks size {}, dropLinks size {}", addLinks.size(), dropLinks.size());
+ // debug prints
+ 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 : addLinks) {
+ filteraddLinks(link);
+ }
+ for (PceLink link : dropLinks) {
+ filterdropLinks(link);
+ }
- // debug prints
- LOG.debug("analyzeNw: azSrgs size = {}", azSrgs.size());
- for (NodeId srg : azSrgs) {
- LOG.debug("analyzeNw: A/Z Srgs SRG = {}", srg.getValue());
- }
- // debug prints
+ } else {
+ // ODU4, 10GE/ODU2e or 1GE/ODU0 services are handled at openroadm-otn layer
+ OpenroadmNodeType typeOfNode = null;
+ for (Node node : allNodes) {
+ String nodeId = node.getNodeId().getValue();
+ if (this.anodeId.equals(nodeId) || (this.znodeId.equals(nodeId))) {
+ typeOfNode = validateOtnNode(node, "AZ");
+ }
+ }
+ if (typeOfNode == null) {
+ LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network");
+ } else if (typeOfNode == OpenroadmNodeType.MUXPDR) {
+ LOG.debug("analyzeNw: A/Z end node are of muxponder type, no intermediate switch allowed on the path");
+ } else {
+ LOG.debug("analyzeNw: A/Z end node are of switch type, searching for potential intermediate switch");
+ for (Node node : allNodes) {
+ String nodeId = node.getNodeId().getValue();
+ if (!(this.anodeId.equals(nodeId) || (this.znodeId.equals(nodeId)))) {
+ // A and Z node have been validated, then if A and Z end nodes are not muxponders
+ // we allow intermediate switch on the path
+ typeOfNode = validateOtnNode(node, "intermediate");
+ }
+ // else : typeOfNode is MUXPDR and we do not authorize any intermediate switch on the path
+ // TODO : handle regens and authorize them on the path if needed
+ }
+ }
- for (PceLink link : addLinks) {
- filteraddLinks(link);
- }
- for (PceLink link : dropLinks) {
- filterdropLinks(link);
+ for (Link link : allLinks) {
+ validateLink(link);
+ }
}
LOG.info("analyzeNw: allPceNodes size {}, allPceLinks size {}", allPceNodes.size(), allPceLinks.size());
if (source == null) {
LOG.debug("validateLink: Link is ignored due source node is rejected by node validation - {}",
- link.getSource().getSourceNode().getValue());
+ link.getSource().getSourceNode().getValue());
return false;
}
if (dest == null) {
LOG.debug("validateLink: Link is ignored due dest node is rejected by node validation - {}",
- link.getDestination().getDestNode().getValue());
+ link.getDestination().getDestNode().getValue());
return false;
}
- PceLink pcelink = new PceLink(link, source, dest);
- if (!pcelink.isValid()) {
- dropOppositeLink(link);
- LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
- return false;
- }
+ if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
+ // 100GE or OTU4 services are handled at WDM Layer
+ PceLink pcelink = new PceLink(link, source, dest);
+ if (!pcelink.isValid()) {
+ dropOppositeLink(link);
+ LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
+ return false;
+ }
+ LinkId linkId = pcelink.getLinkId();
+ 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:
+ case EXPRESSLINK:
+ allPceLinks.put(linkId, pcelink);
+ source.addOutgoingLink(pcelink);
+ LOG.debug("validateLink: {}-LINK added to allPceLinks {}",
+ pcelink.getlinkType(), pcelink.toString());
+ break;
+ case ADDLINK:
+ pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString(), true));
+ addLinks.add(pcelink);
+ LOG.debug("validateLink: ADD-LINK saved {}", pcelink.toString());
+ break;
+ case DROPLINK:
+ pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString(), false));
+ dropLinks.add(pcelink);
+ LOG.debug("validateLink: DROP-LINK saved {}", pcelink.toString());
+ break;
+ case XPONDERINPUT:
+ // store separately all SRG links directly
+ azSrgs.add(sourceId);
+ // 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.getClient(pcelink.getDestTP().toString()));
+ allPceLinks.put(linkId, pcelink);
+ source.addOutgoingLink(pcelink);
+ LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink.toString());
+ break;
+ // does it mean XPONDER==>>SRG ?
+ case XPONDEROUTPUT:
+ // store separately all SRG links directly
+ azSrgs.add(destId);
+ // 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.getClient(pcelink.getSourceTP().toString()));
+ allPceLinks.put(linkId, pcelink);
+ source.addOutgoingLink(pcelink);
+ 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;
- LinkId linkId = pcelink.getLinkId();
+ } else if (("ODU4".equals(serviceType)) || ("10GE".equals(serviceType)) || ("1GE".equals(serviceType))) {
+ // ODU4, 1GE and 10GE services relying on ODU2, ODU2e or ODU0 services are handled at OTN layer
+ PceLink pceOtnLink = new PceLink(link, source, dest);
- switch (validateLinkConstraints(pcelink)) {
- case HARD_EXCLUDE :
+ if (!pceOtnLink.isOtnValid(link, serviceType)) {
dropOppositeLink(link);
- LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue());
+ LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
return false;
- default:
- break;
- }
+ }
- switch (pcelink.getlinkType()) {
- case ROADMTOROADM :
- allPceLinks.put(linkId, pcelink);
- source.addOutgoingLink(pcelink);
- LOG.debug("validateLink: ROADMTOROADM-LINK added to allPceLinks {}", pcelink.toString());
- break;
- case EXPRESSLINK :
- allPceLinks.put(linkId, pcelink);
- source.addOutgoingLink(pcelink);
- LOG.debug("validateLink: EXPRESS-LINK added to allPceLinks {}", pcelink.toString());
- break;
- case ADDLINK :
- pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString(), true));
- addLinks.add(pcelink);
- LOG.debug("validateLink: ADD-LINK saved {}", pcelink.toString());
- break;
- case DROPLINK :
- pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString(), false));
- dropLinks.add(pcelink);
- LOG.debug("validateLink: DROP-LINK saved {}", pcelink.toString());
- break;
- case XPONDERINPUT :
- // store separately all SRG links directly
- azSrgs.add(sourceId);
- // 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.getClient(pcelink.getDestTP().toString()));
- allPceLinks.put(linkId, pcelink);
- source.addOutgoingLink(pcelink);
- LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink.toString());
- break;
- // does it mean XPONDER==>>SRG ?
- case XPONDEROUTPUT :
- // store separately all SRG links directly
- azSrgs.add(destId);
- // connected to A/Z
- if (!source.checkTP(pcelink.getSourceTP().toString())) {
- LOG.debug("validateLink: XPONDER-OUTPUT is rejected as NW port is busy - {} ", pcelink.toString());
+ LinkId linkId = pceOtnLink.getLinkId();
+ switch (validateLinkConstraints(pceOtnLink)) {
+ case HARD_EXCLUDE:
+ dropOppositeLink(link);
+ LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue());
return false;
- }
- pcelink.setClient(source.getClient(pcelink.getSourceTP().toString()));
- allPceLinks.put(linkId, pcelink);
- source.addOutgoingLink(pcelink);
- LOG.debug("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink.toString());
- break;
- default:
- LOG.warn("validateLink: link type is not supported {}", pcelink.toString());
+ default:
+ break;
+ }
+ switch (pceOtnLink.getlinkType()) {
+ case OTNLINK:
+ allPceLinks.put(linkId, pceOtnLink);
+ source.addOutgoingLink(pceOtnLink);
+ LOG.debug("validateLink: OTN-LINK added to allPceLinks {}", pceOtnLink.toString());
+ break;
+ default:
+ LOG.warn("validateLink: link type is not supported {}", pceOtnLink.toString());
+ }
+ return true;
+ } else {
+ LOG.error(" validateLink: Unmanaged service type {}", serviceType);
+ return false;
}
- return true;
}
private boolean validateNode(Node node) {
}
OpenroadmNodeType nodeType = node1.getNodeType();
- PceNode pceNode = new PceNode(node,nodeType,node.getNodeId());
+ PceNode pceNode = new PceNode(node, nodeType, node.getNodeId());
pceNode.validateAZxponder(anodeId, znodeId);
pceNode.initWLlist();
}
switch (validateNodeConstraints(pceNode)) {
- case HARD_EXCLUDE :
+ case HARD_EXCLUDE:
return false;
- default :
+ default:
break;
}
-
- if (pceNode.getSupNodeIdPceNode().equals(this.anodeId)) {
- if (this.aendPceNode != null) {
- LOG.debug("aendPceNode already gets: {}", this.aendPceNode);
- } else if (endPceNode(nodeType,pceNode.getNodeId(), pceNode)) {
- this.aendPceNode = pceNode;
- }
- // returning false otherwise would break E2E test
+ if ((pceNode.getSupNetworkNodeIdPceNode().equals(anodeId) && (this.aendPceNode == null))
+ && (endPceNode(nodeType, pceNode.getNodeId(), pceNode))) {
+ this.aendPceNode = pceNode;
}
- if (pceNode.getSupNodeIdPceNode().equals(this.znodeId)) {
- if (this.zendPceNode != null) {
- LOG.debug("zendPceNode already gets: {}", this.zendPceNode);
- } else if (endPceNode(nodeType,pceNode.getNodeId(), pceNode)) {
- this.zendPceNode = pceNode;
- }
- // returning false otherwise would break E2E test
+ if ((pceNode.getSupNetworkNodeIdPceNode().equals(znodeId) && (this.zendPceNode == null))
+ && (endPceNode(nodeType, pceNode.getNodeId(), pceNode))) {
+ this.zendPceNode = pceNode;
}
allPceNodes.put(pceNode.getNodeId(), pceNode);
return true;
}
+ private OpenroadmNodeType validateOtnNode(Node node, String mode) {
+
+ LOG.debug("validateNode: node {} ", node.toString());
+ // PceOtnNode 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());
+ }
+ OpenroadmNodeType nodeType = node1.getNodeType();
+
+ PceOtnNode pceOtnNode = new PceOtnNode(node, nodeType, node.getNodeId(), serviceType);
+ if (mode == "AZ") {
+ pceOtnNode.validateAZxponder(anodeId, znodeId);
+ } else if (mode == "intermediate") {
+ pceOtnNode.validateIntermediateSwitch();
+ } else {
+ LOG.error("validateOtnNode: unproper mode passed to the method : {} not supported", mode);
+ return null;
+ }
+
+ if (!pceOtnNode.isValid()) {
+ LOG.warn(" validateNode: Node is ignored");
+ return null;
+ }
+
+ switch (validateNodeConstraints(pceOtnNode)) {
+ case HARD_EXCLUDE:
+ return null;
+
+ default:
+ break;
+ }
+
+ if ((pceOtnNode.getNodeId().equals(anodeId))) {
+ this.aendPceNode = pceOtnNode;
+ }
+ if ((pceOtnNode.getNodeId().equals(znodeId))) {
+ this.zendPceNode = pceOtnNode;
+ }
+
+ allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode);
+ LOG.debug("validateNode: node is saved {}", pceOtnNode.getNodeId().getValue());
+ return nodeType;
+ }
+
private ConstraintTypes validateNodeConstraints(PceNode pcenode) {
if (pceHardConstraints.getExcludeSupNodes().isEmpty() && pceHardConstraints.getExcludeCLLI().isEmpty()) {
return ConstraintTypes.NONE;
}
- if (pceHardConstraints.getExcludeSupNodes().contains(pcenode.getSupNodeIdPceNode())) {
+ if (pceHardConstraints.getExcludeSupNodes().contains(pcenode.getSupNetworkNodeIdPceNode())) {
LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
return ConstraintTypes.HARD_EXCLUDE;
}
private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceNode pceNode) {
switch (openroadmNodeType) {
- case SRG :
+ case SRG:
pceNode.initSrgTps();
this.azSrgs.add(nodeId);
break;
- case XPONDER :
+ case XPONDER:
pceNode.initXndrTps();
break;
default:
return this.allPceLinks;
}
+ public String getServiceType() {
+ return serviceType;
+ }
+
public PceResult getReturnStructure() {
return returnStructure;
}
}
}
- /*private static void printLinksInfo(Map<LinkId, PceLink> allpcelinks) {
- Iterator<Map.Entry<LinkId, PceLink>> links = allpcelinks.entrySet().iterator();
- while (links.hasNext()) {
- LOG.info("In printLinksInfo link {} : ", links.next().getValue().toString());
- }
- }*/
-
}
*/
double weight = 0;
private boolean isValid = true;
+ private boolean isOtnValid = true;
+
// this member is for XPONDER INPUT/OUTPUT links.
// it keeps name of client corresponding to NETWORK TP
private String client = "";
private final Object destTP;
private final String sourceSupNodeId;
private final String destSupNodeId;
+ 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 List<Long> srlgList;
private final double osnr;
private final Span omsAttributesSpan;
this.sourceSupNodeId = source.getSupNodeIdPceNode();
this.destSupNodeId = dest.getSupNodeIdPceNode();
+ this.sourceNetworkSupNodeId = source.getSupNetworkNodeIdPceNode();
+ this.destNetworkSupNodeId = dest.getSupNetworkNodeIdPceNode();
- this.sourceCLLI = source.getCLLI();
- this.destCLLI = dest.getCLLI();
+ this.sourceCLLI = source.getClliSupNodeId();
+ this.destCLLI = dest.getClliSupNodeId();
this.linkType = MapUtils.calcType(link);
this.srlgList = MapUtils.getSRLG(link);
this.latency = calcLatency(link);
this.osnr = calcSpanOSNR();
+ this.availableBandwidth = 0L;
+ } else if (this.linkType == OpenroadmLinkType.OTNLINK) {
+ this.availableBandwidth = MapUtils.getAvailableBandwidth(link);
+ this.srlgList = MapUtils.getSRLGfromLink(link);
+ this.osnr = 0.0;
+ this.latency = 0L;
+ this.omsAttributesSpan = null;
} else {
this.omsAttributesSpan = null;
this.srlgList = null;
this.latency = 0L;
this.osnr = 100L; //infinite OSNR in DB
+ this.availableBandwidth = 0L;
}
-
LOG.debug("PceLink: created PceLink {}", toString());
}
return latency.doubleValue();
}
+ public Long getAvailableBandwidth() {
+ return availableBandwidth;
+ }
+
+
public String getsourceSupNodeId() {
return sourceSupNodeId;
}
+ public String getsourceNetworkSupNodeId() {
+ return sourceNetworkSupNodeId;
+ }
+
public String getdestSupNodeId() {
return destSupNodeId;
}
+ public String getdestNetworkSupNodeId() {
+ return destNetworkSupNodeId;
+ }
+
public List<Long> getsrlgList() {
return srlgList;
}
return isValid;
}
+ public boolean isOtnValid(Link link, String oduType) {
+ if (this.linkType == OpenroadmLinkType.OTNLINK) {
+ isOtnValid = false;
+ Long availableBW = MapUtils.getAvailableBandwidth(link);
+ if ((availableBW == 0L) || (availableBW == null)) {
+ LOG.error("PceLink: No bandwidth available or not valid OTN Link, Link {} is ignored ", linkId);
+ } else if (("ODU4".equals(oduType)) && (availableBW == 100000L)) {
+ isOtnValid = true;
+ LOG.debug("PceLink: Selected OTU4 Link {} is eligible for ODU creation OTN Link", linkId);
+ } else if (("ODU2".equals(oduType)) || ("ODU2e".equals(oduType)) && (availableBW >= 12500L)) {
+ isOtnValid = true;
+ LOG.debug("PceLink: Selected ODU4 Link {} has available bandwidth and is eligible for {} creation ",
+ linkId, oduType);
+ } else if (("ODU0".equals(oduType)) && (availableBW >= 1250L)) {
+ isOtnValid = true;
+ LOG.debug("PceLink: Selected ODU4 Link {} has available bandwidth and is eligible for {} creation ",
+ linkId, oduType);
+ } else if (("ODU1".equals(oduType)) && (availableBW >= 2500L)) {
+ isOtnValid = true;
+ LOG.debug("PceLink: Selected ODU4 Link {} has available bandwidth and is eligible for {} creation ",
+ linkId, oduType);
+ } else {
+ isOtnValid = false;
+ LOG.error(
+ "PceLink: Selected OTN Link {} is not eligible for ODU creation: not enough available bandwidth",
+ linkId);
+ }
+
+ } else {
+ isOtnValid = false;
+ LOG.error("PceLink: Not an OTN link. Link is ignored {}", linkId);
+ }
+
+ if ((this.linkId == null) || (this.linkType == null)
+ || (this.oppositeLink == null)) {
+ isOtnValid = 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)) {
+ isOtnValid = false;
+ LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", linkId);
+ }
+ if ((this.sourceNetworkSupNodeId.equals("")) || (this.destNetworkSupNodeId.equals(""))) {
+ isOtnValid = false;
+ LOG.error("PceLink: No Link source SuppNodeID or destination SuppNodeID is available. Link is ignored {}",
+ linkId);
+ }
+ if ((this.sourceCLLI.equals("")) || (this.destCLLI.equals(""))) {
+ isOtnValid = false;
+ LOG.error("PceLink: No Link source CLLI or destination CLLI is available. Link is ignored {}", linkId);
+ }
+
+ return isOtnValid;
+ }
+
public String toString() {
return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latency=" + latency;
}
import java.util.Optional;
import java.util.TreeMap;
+import org.opendaylight.transportpce.common.NetworkUtils;
import org.opendaylight.transportpce.pce.SortPortsByName;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1;
import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
private boolean valid = true;
- private final Node node;
- private final NodeId nodeId;
- private final OpenroadmNodeType nodeType;
+ protected final Node node;
+ protected final NodeId nodeId;
+ protected final OpenroadmNodeType nodeType;
private final String supNodeId;
+ private final String supNetworkNodeId;
private final String clli;
// wavelength calculation per node type
private List<String> usedXpndrNWTps = new ArrayList<String>();
private List<PceLink> outgoingLinks = new ArrayList<PceLink>();
private Map<String, String> clientPerNwTp = new HashMap<String, String>();
+ private Map<String,List<Integer>> tpAvailableTribPort = new TreeMap<String,List<Integer>>();
+ private Map<String,List<Integer>> tpAvailableTribSlot = new TreeMap<String,List<Integer>>();
public PceNode(Node node, OpenroadmNodeType nodeType, NodeId nodeId) {
this.node = node;
this.nodeId = nodeId;
this.nodeType = nodeType;
this.supNodeId = getSupNodeId(node);
- this.clli = MapUtils.getCLLI(node);
+ this.supNetworkNodeId = getNetworkSupNodeId(node);
+ //this.clli = MapUtils.getCLLI(node);
+ this.clli = getClliSupNodeId(node);
+ this.tpAvailableTribPort.clear();
+ this.tpAvailableTribSlot.clear();
if ((node == null) || (nodeId == null) || (nodeType == null)) {
LOG.error("PceNode: one of parameters is not populated : nodeId, node type");
}
}
+ private String getClliSupNodeId(Node inputNode) {
+ TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
+ String tempNetworkSupNodeId = "";
+ allSupNodes = MapUtils.getAllSupNode(inputNode);
+ if (allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID) == null) {
+ LOG.error("getClliSupNodeId: No Supporting node at CLLI layer for node: [{}].", inputNode.getNodeId());
+ } else {
+ tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID);
+ }
+ return tempNetworkSupNodeId;
+ }
+
+ public String getClliSupNodeId() {
+ return clli;
+ }
+
+ private String getNetworkSupNodeId(Node inputNode) {
+ TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
+ String tempNetworkSupNodeId = "";
+ allSupNodes = MapUtils.getAllSupNode(inputNode);
+ if (allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID) == null) {
+ LOG.error(
+ "getNetworkSupNodeId: No Supporting node at NETWORK layer for node: [{}].", inputNode.getNodeId());
+ } else {
+ tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID);
+ }
+ return tempNetworkSupNodeId;
+ }
+
+
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))) {
-
+ if (this.supNetworkNodeId.equals(anodeId) || (this.supNetworkNodeId.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 boolean isValid() {
- if ((node == null) || (nodeId == null) || (nodeType == null) || (supNodeId == null) || (clli == null)) {
+ if ((node == null) || (nodeId == null) || (nodeType == null) || (supNetworkNodeId == null) || (clli == null)) {
LOG.error("PceNode: one of parameters is not populated : nodeId, node type, supporting nodeId");
valid = false;
}
return supNodeId;
}
+ public String getSupNetworkNodeIdPceNode() {
+ return supNetworkNodeId;
+ }
+
public String getCLLI() {
return clli;
}
LOG.info(" outgoing links of node {} : {} ", nodeId.getValue(), this.getOutgoingLinks().toString());
}
+ public Map<String,List<Integer>> getAvailableTribPorts() {
+ return tpAvailableTribPort;
+ }
+
+ public Map<String,List<Integer>> getAvailableTribSlots() {
+ return tpAvailableTribSlot;
+ }
+
}
--- /dev/null
+/*
+ * Copyright © 2019 Orange, 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.networkanalyzer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+//import java.util.Optional;
+import java.util.TreeMap;
+
+//import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.transportpce.common.NetworkUtils;
+//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;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.OduSwitchingPools;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.xpdr.tp.supported.interfaces.SupportedInterfaceCapability;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODTU4TsAllocated;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.networks.network.node.SwitchingPools;
+//import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If100GEODU4;
+//import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If10GEODU2e;
+//import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If1GEODU0;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev181130.xpdr.otn.tp.attributes.OdtuTpnPool;
+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.rev180226.networks.network.Node;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PceOtnNode extends PceNode {
+ /* Logging. */
+ private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
+ ////////////////////////// OTN NODES ///////////////////////////
+ /*
+ * For This Class the node passed shall be at the otn-openroadm Layer
+ */
+
+ private boolean valid = true;
+
+ private final String supNetworkNodeId;
+ private final String supTopoNodeId;
+ private final String clli;
+ private final String otnServiceType;
+
+ private Map<String, List<Integer>> tpAvailableTribPort = new TreeMap<String, List<Integer>>();
+ private Map<String, List<Integer>> tpAvailableTribSlot = new TreeMap<String, List<Integer>>();
+ private Map<String, OpenroadmTpType> availableXponderTp = new TreeMap<String, OpenroadmTpType>();
+ private List<String> usedXpdrNWTps = new ArrayList<String>();
+ private List<String> unusableXpdrNWTps = new ArrayList<String>();
+ private List<String> usedXpdrClientTps = new ArrayList<String>();
+ private List<String> unusableXpdrClientTps = new ArrayList<String>();
+ private List<PceLink> outgoingLinks = new ArrayList<PceLink>();
+ private Map<String, String> clientPerNwTp = new HashMap<String, String>();
+
+ public PceOtnNode(Node node, OpenroadmNodeType nodeType, NodeId nodeId, String serviceType) {
+ super(node, nodeType, nodeId);
+ this.supNetworkNodeId = getNetworkSupNodeId(node);
+ this.supTopoNodeId = getTopoSupNodeId(node);
+ this.clli = getClliSupNodeId(node);
+ this.otnServiceType = serviceType;
+ this.tpAvailableTribPort.clear();
+ this.tpAvailableTribSlot.clear();
+ this.usedXpdrNWTps.clear();
+ this.unusableXpdrNWTps.clear();
+ this.usedXpdrClientTps.clear();
+ this.unusableXpdrClientTps.clear();
+
+ if ((node == null) || (nodeId == null) || (nodeType == null)) {
+ LOG.error("PceOtnNode: one of parameters is not populated : nodeId, node type");
+ this.valid = false;
+ }
+ }
+
+ public void initXndrTps(String mode) {
+ LOG.info("initXndrTps for node : {}", this.nodeId);
+ int availableNetworkTpNumber = 0;
+ int availableClientTpNumber = 0;
+
+ this.availableXponderTp.clear();
+
+ if (!isValid()) {
+ return;
+ }
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
+ this.node.augmentation(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class);
+ List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
+ .network.node.TerminationPoint> allTps = nodeTp.getTerminationPoint();
+ this.valid = false;
+ if (allTps == null) {
+ LOG.error("initXndrTps: XPONDER TerminationPoint list is empty for node {}", this.toString());
+ return;
+ }
+
+ for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
+ .network.node.TerminationPoint tp : allTps) {
+ TerminationPoint1 otnTp1 = tp.augmentation(TerminationPoint1.class);
+ //TODO many nested if-structures below, this needs to be reworked
+ if (otnTp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
+ if (otnTp1.getXpdrTpPortConnectionAttributes().getWavelength() != null) {
+ this.usedXpdrNWTps.add(tp.getTpId().getValue());
+ } else {
+ // find server of this network TP
+ String server = otnTp1.getXpdrTpPortConnectionAttributes().getTailEquipmentId();
+ if ((server.equals("")) || (server == null)) {
+ this.unusableXpdrNWTps.add(tp.getTpId().getValue());
+ } else {
+ // tp is not used and as a tail to server WDM layer
+ if (("10GE".equals(this.otnServiceType)) || ("1GE".equals(this.otnServiceType))) {
+ // LO-ODU needs to be created on a parent HO-ODU
+ // interface
+ List<OdtuTpnPool> presenceOdtu =
+ otnTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool();
+ if (presenceOdtu == null) {
+ this.unusableXpdrNWTps.add(tp.getTpId().getValue());
+ } else {
+ List<SupportedInterfaceCapability> sic =
+ otnTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability();
+ if ((findNetworkCompliantInterface(sic)) & (checkAvailableTribPort(tp))
+ & (checkAvailableTribSlot(tp))) {
+ this.availableXponderTp.put(tp.getTpId().getValue(),
+ OpenroadmTpType.XPONDERNETWORK);
+ availableNetworkTpNumber++;
+ }
+ /*
+ * Add the retrieval of outgoing ingoing links
+ * through an external function
+ */
+ }
+ } else {
+ // service is HO service
+ List<SupportedInterfaceCapability> sic =
+ otnTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability();
+ if (findNetworkCompliantInterface(sic)) {
+ this.availableXponderTp.put(tp.getTpId().getValue(), OpenroadmTpType.XPONDERNETWORK);
+ availableNetworkTpNumber++;
+ /*
+ * Add the retrieval of outgoing ingoing links
+ * through an external function
+ */
+ } else {
+ this.unusableXpdrNWTps.add(tp.getTpId().getValue());
+
+ }
+
+ }
+
+ }
+
+ }
+
+ // The port is not a network port
+ } else if (otnTp1.getTpType() == OpenroadmTpType.XPONDERCLIENT) {
+ // For Client port we verify that it supports needed interfaces
+ // TBD : How shall we check a client port is available and not
+ // in use?
+ List<SupportedInterfaceCapability> sic =
+ otnTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability();
+ if (findClientCompliantInterface(sic)) {
+ this.availableXponderTp.put(tp.getTpId().getValue(), OpenroadmTpType.XPONDERCLIENT);
+ availableClientTpNumber++;
+ }
+ }
+ LOG.debug("initXndrTps: XPONDER tp = {} is used", tp.getTpId().getValue());
+ LOG.error("initXndrTps: XPONDER {} NW TP doesn't have defined server ROADM SRG {}", this.toString(), tp
+ .getTpId().getValue());
+ }
+ if ("AZ".equals(mode)) {
+ if ((availableClientTpNumber >= 1) || (availableNetworkTpNumber >= 1)) {
+ // for A and Z node we need to have one valid client port & one
+ // valid network port
+ this.valid = true;
+ }
+ } else if ("intermediate".equals(mode)) {
+ if ((availableNetworkTpNumber >= 2)) {
+ // for OTN switching node used in transit we need to have two
+ // valid network ports
+ this.valid = true;
+ }
+ }
+
+ if (!isValid()) {
+ LOG.debug("initXndrTps: XPONDER doesn't have the required ports available {}", this.toString());
+ return;
+ } else {
+ LOG.debug("initXndrTps: XPONDER {} is elligible", this.toString());
+ }
+ }
+
+ private Boolean findClientCompliantInterface(List<SupportedInterfaceCapability> sic) {
+ boolean compliant = false;
+ for (SupportedInterfaceCapability sit : sic) {
+ String interfacetype = sit.getIfCapType().toString();
+ switch (interfacetype) {
+ case "If1GEODU0":
+ case "If1GE":
+ if ("1GE".equals(this.otnServiceType)) {
+ compliant = true;
+ }
+ break;
+ case "If10GEODU2e":
+ case "If10GE":
+ if ("10GE".equals(this.otnServiceType)) {
+ compliant = true;
+ }
+ break;
+ case "If100GEODU4":
+ case "If100GE":
+ if ("100GE".equals(this.otnServiceType)) {
+ compliant = true;
+ }
+ break;
+ case "IfOTU4ODU4":
+ case "IfOCHOTU4ODU4":
+ if (("OTU4".equals(this.otnServiceType)) || ("ODU4".equals(this.otnServiceType))) {
+ compliant = true;
+ }
+ break;
+ default:
+ compliant = false;
+ break;
+ }
+
+ }
+ return compliant;
+ }
+
+ private Boolean findNetworkCompliantInterface(List<SupportedInterfaceCapability> sic) {
+ boolean compliant = false;
+ for (SupportedInterfaceCapability sit : sic) {
+ String interfacetype = sit.getIfCapType().toString();
+ switch (interfacetype) {
+ case "IfOTU4ODU4":
+ case "IfOCHOTU4ODU4":
+ compliant = true;
+ break;
+ case "IfOTU2ODU2":
+ case "IfOCHOTU2ODU2":
+ if (("1GE".equals(this.otnServiceType)) || ("10GE".equals(this.otnServiceType))) {
+ compliant = true;
+ }
+ break;
+ // add all use case with higher rate interfaces when it shows up
+ default:
+ compliant = false;
+ break;
+ }
+
+ }
+ return compliant;
+ }
+
+ private String getClliSupNodeId(Node inputNode) {
+ TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
+ String tempNetworkSupNodeId = "";
+ allSupNodes = MapUtils.getAllSupNode(inputNode);
+ if (allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID) == null) {
+ LOG.error("getClliSupNodeId: No Supporting node at CLLI layer for node: [{}].", inputNode.getNodeId());
+ } else {
+ tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID);
+ }
+ return tempNetworkSupNodeId;
+ }
+
+ private String getNetworkSupNodeId(Node inputNode) {
+ TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
+ String tempNetworkSupNodeId = "";
+ allSupNodes = MapUtils.getAllSupNode(inputNode);
+ if (allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID) == null) {
+ LOG.error(
+ "getNetworkSupNodeId: No Supporting node at NETWORK layer for node: [{}].", inputNode.getNodeId());
+ } else {
+ tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID);
+ }
+ return tempNetworkSupNodeId;
+ }
+
+ private String getTopoSupNodeId(Node inputNode) {
+ TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
+ String tempTopoSupNodeId = "";
+ allSupNodes = MapUtils.getAllSupNode(inputNode);
+ if (allSupNodes.get(NetworkUtils.OVERLAY_NETWORK_ID) == null) {
+ LOG.error(
+ "getTopologySupNodeId: No Supporting node at TOPOLOGY layer for node: [{}].", inputNode.getNodeId());
+ } else {
+ tempTopoSupNodeId = allSupNodes.get(NetworkUtils.OVERLAY_NETWORK_ID);
+ }
+ return tempTopoSupNodeId;
+ }
+
+ public void validateAZxponder(String anodeId, String znodeId) {
+ if (!isValid()) {
+ return;
+ }
+ if ((this.nodeType != OpenroadmNodeType.MUXPDR) & (this.nodeType != OpenroadmNodeType.SWITCH)
+ & (this.nodeType != OpenroadmNodeType.TPDR)) {
+ return;
+ }
+ // Detect A and Z, a/znodeId correspond to otn layer, supporting node
+ // might be of Network or Topology layer
+ if (this.nodeId.equals(anodeId) || (this.nodeId.equals(znodeId))) {
+ initXndrTps("AZ");
+ if (!this.valid) {
+ LOG.debug("validateAZxponder: XPONDER unusable for A or Z == {}", nodeId.getValue());
+ } else {
+ LOG.info("validateAZxponder: A or Z node detected and validated == {}", nodeId.getValue());
+ }
+ return;
+ } else {
+ LOG.debug("validateAZxponder: XPONDER is ignored == {}", nodeId.getValue());
+ valid = false;
+ }
+
+ }
+
+ public boolean validateSwitchingPoolBandwidth(
+ Node node,
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
+ .network.node.TerminationPoint tp1,
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
+ .network.node.TerminationPoint tp2,
+ Long neededBW) {
+ Long availableBW = 0L;
+ if (this.nodeType != OpenroadmNodeType.TPDR) {
+ return true;
+ } else {
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1 node1 =
+ node.augmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1.class);
+ SwitchingPools sp = node1.getSwitchingPools();
+ List<OduSwitchingPools> osp = new ArrayList<OduSwitchingPools>();
+ osp = sp.getOduSwitchingPools();
+ for (OduSwitchingPools ospx : osp) {
+ List<NonBlockingList> nbl = ospx.getNonBlockingList();
+ for (NonBlockingList nbll : nbl) {
+ if (nbll.getAvailableInterconnectBandwidth() >= neededBW) {
+ List<TpId> tplist = new ArrayList<TpId>(nbll.getTpList());
+ if ((tplist.contains(tp1.getTpId())) & (tplist.contains(tp2.getTpId()))) {
+ LOG.debug("validateSwitchingPoolBandwidth: couple of tp {} x {} valid for crossconnection",
+ tp1.getTpId().toString(), tp2.getTpId().toString());
+ return true;
+ }
+ }
+ }
+
+ }
+ LOG.debug("validateSwitchingPoolBandwidth: No valid Switching pool for crossconnecting tp {} and {}",
+ tp1.getTpId().toString(), tp2.getTpId().toString());
+ return false;
+ }
+
+ }
+
+ public void validateIntermediateSwitch() {
+ if (!isValid()) {
+ return;
+ }
+ if (this.nodeType != OpenroadmNodeType.SWITCH) {
+ return;
+ }
+ // Validate switch for use as an intermediate XPONDER on the path
+ initXndrTps("intermediate");
+ if (!this.valid) {
+ LOG.debug("validateIntermediateSwitch: Switch unusable for transit == {}", nodeId.getValue());
+ } else {
+ LOG.info("validateIntermediateSwitch: Switch usable for transit == {}", nodeId.getValue());
+ }
+ return;
+
+ }
+
+ public boolean checkAvailableTribPort(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
+ .network.node.TerminationPoint tp) {
+ boolean compatibleSupInt = false;
+ TerminationPoint1 otnTp1 = tp.augmentation(TerminationPoint1.class);
+ if (otnTp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
+ try {
+ List<OdtuTpnPool> otpp = otnTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool();
+
+ for (OdtuTpnPool otppi : otpp) {
+ if (otppi.getOdtuType().getClass().equals(ODTU4TsAllocated.class)) {
+ this.tpAvailableTribPort.put(tp.getTpId().getValue(), otppi.getTpnPool());
+ LOG.debug("checkAvailableTribPort: tp {} and his trib Ports have been added to "
+ + "tpAvailableTribPortMap", tp.getTpId().getValue());
+ compatibleSupInt = true;
+
+ }
+ }
+ } catch (NullPointerException e) {
+ LOG.debug("checkAvailableTribPort: OdtuTpnPool not present for tp {} ", tp.getTpId().toString());
+ }
+
+ } else {
+ LOG.debug("checkAvailableTribPort: tp {} has no odtu tpn Pool", tp.getTpId().getValue());
+ }
+ return compatibleSupInt;
+ }
+
+ public boolean checkAvailableTribSlot(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
+ .network.node.TerminationPoint tp) {
+ boolean compatibleSupInt = false;
+ TerminationPoint1 otnTp1 = tp.augmentation(TerminationPoint1.class);
+ if (otnTp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
+ List<OdtuTpnPool> otpp;
+ try {
+ otpp = otnTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool();
+
+ for (OdtuTpnPool otppi : otpp) {
+ if (otppi.getOdtuType().getClass().equals(ODTU4TsAllocated.class)) {
+ this.tpAvailableTribSlot.put(
+ tp.getTpId().getValue(),
+ otnTp1.getXpdrTpPortConnectionAttributes().getTsPool());
+ LOG.debug(
+ "checkAvailableTribPort: tp {} and its trib Slots were added to tpAvailableTribSlotMap",
+ tp.getTpId().getValue());
+ compatibleSupInt = true;
+
+ }
+ }
+
+ } catch (NullPointerException e) {
+ LOG.debug("checkAvailableTribSlot: OdtuTpnPool not present for tp {} ", tp.getTpId().toString());
+ }
+ } else {
+ LOG.debug("checkAvailableTribPort: tp {} is not a network Port", tp.getTpId().getValue());
+ }
+ return compatibleSupInt;
+ }
+
+ public String getXpdrClient(String tp) {
+ return this.clientPerNwTp.get(tp);
+ }
+
+ public boolean checkTP(String tp) {
+ return !((this.usedXpdrNWTps.contains(tp)) || (this.usedXpdrClientTps.contains(tp))
+ || (this.unusableXpdrNWTps.contains(tp)) || (this.unusableXpdrClientTps.contains(tp)));
+ }
+
+ public boolean isValid() {
+ if ((node == null) || (nodeId == null) || (nodeType == null) || (supNetworkNodeId == null) || (clli == null)) {
+ LOG.error("PceNode: one of parameters is not populated : nodeId, node type, supporting nodeId");
+ valid = false;
+ }
+ return valid;
+ }
+
+ public Map<String, OpenroadmTpType> getAvailableTps() {
+ return availableXponderTp;
+ }
+
+ public void addOutgoingLink(PceLink outLink) {
+ this.outgoingLinks.add(outLink);
+ }
+
+ public List<PceLink> getOutgoingLinks() {
+ return outgoingLinks;
+ }
+
+ public String getClient(String tp) {
+ return clientPerNwTp.get(tp);
+ }
+
+ public String getTopoSupNodeIdPceNode() {
+ return supTopoNodeId;
+ }
+
+ public String getNetworkSupNodeIdPceNode() {
+ return supNetworkNodeId;
+ }
+
+ public String getCLLI() {
+ return clli;
+ }
+
+ public String toString() {
+ return "PceNode type=" + nodeType + " ID=" + nodeId.getValue() + " CLLI=" + clli;
+ }
+
+ public void printLinksOfNode() {
+ LOG.info(" outgoing links of node {} : {} ", nodeId.getValue(), this.getOutgoingLinks().toString());
+ }
+
+ public Map<String, List<Integer>> getAvailableTribPorts() {
+ return tpAvailableTribPort;
+ }
+
+ public Map<String, List<Integer>> getAvailableTribSlots() {
+ return tpAvailableTribSlot;
+ }
+
+}
package org.opendaylight.transportpce.pce.networkanalyzer;
import org.opendaylight.transportpce.common.ResponseCodes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev190531.ServiceFormat;
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;
private String responseCode = ResponseCodes.RESPONSE_FAILED;
private long resultWavelength = -1;
private long rate = -1;
+ private ServiceFormat serviceFormat = ServiceFormat.OC;
public enum LocalCause {
NONE, TOO_HIGH_LATENCY, OUT_OF_SPEC_OSNR, NO_PATH_EXISTS, INT_PROBLEM, HD_NODE_INCLUDE;
this.rate = rate;
}
+ public ServiceFormat getServiceFormat() {
+ return serviceFormat;
+ }
+
+ public void setServiceFormat(ServiceFormat serviceFormat) {
+ this.serviceFormat = serviceFormat;
+ }
+
public LocalCause getLocalCause() {
return localCause;
}
<network-ref>openroadm-network</network-ref>
<node-ref>ROADMC01</node-ref>
</supporting-node>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeC</node-ref>
+ </supporting-node>
<srg-attributes xmlns="http://org/openroadm/network/topology">
<available-wavelengths>
<index>93</index>
<tp-id>DEG1-TTP-TXRX</tp-id>
<tp-type xmlns="http://org/openroadm/common/network">DEGREE-TXRX-TTP</tp-type>
</termination-point>
+ <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
<supporting-node>
<network-ref>openroadm-network</network-ref>
<node-ref>ROADMC01</node-ref>
</supporting-node>
- <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeC</node-ref>
+ </supporting-node>
<degree-attributes xmlns="http://org/openroadm/network/topology">
<degree-number>1</degree-number>
<available-wavelengths>
<tp-id>DEG2-CTP-TXRX</tp-id>
<tp-type xmlns="http://org/openroadm/common/network">DEGREE-TXRX-CTP</tp-type>
</termination-point>
+ <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
<supporting-node>
<network-ref>openroadm-network</network-ref>
<node-ref>ROADMC01</node-ref>
</supporting-node>
- <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeC</node-ref>
+ </supporting-node>
<degree-attributes xmlns="http://org/openroadm/network/topology">
<degree-number>2</degree-number>
<available-wavelengths>
<network-ref>openroadm-network</network-ref>
<node-ref>ROADMA01</node-ref>
</supporting-node>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeA</node-ref>
+ </supporting-node>
<srg-attributes xmlns="http://org/openroadm/network/topology">
<available-wavelengths>
<index>93</index>
<tp-type xmlns="http://org/openroadm/common/network">XPONDER-NETWORK</tp-type>
<associated-connection-map-port xmlns="http://transportpce/topology">XPDR1-CLIENT1</associated-connection-map-port>
</termination-point>
+ <node-type xmlns="http://org/openroadm/common/network">XPONDER</node-type>
<supporting-node>
<network-ref>openroadm-network</network-ref>
<node-ref>XPDRA01</node-ref>
</supporting-node>
- <node-type xmlns="http://org/openroadm/common/network">XPONDER</node-type>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeA</node-ref>
+ </supporting-node>
</node>
<node>
<node-id>ROADMA01-DEG2</node-id>
<tp-id>DEG2-CTP-TXRX</tp-id>
<tp-type xmlns="http://org/openroadm/common/network">DEGREE-TXRX-CTP</tp-type>
</termination-point>
+ <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
<supporting-node>
<network-ref>openroadm-network</network-ref>
<node-ref>ROADMA01</node-ref>
</supporting-node>
- <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeA</node-ref>
+ </supporting-node>
<degree-attributes xmlns="http://org/openroadm/network/topology">
<degree-number>2</degree-number>
<available-wavelengths>
<tp-type xmlns="http://org/openroadm/common/network">XPONDER-NETWORK</tp-type>
<associated-connection-map-port xmlns="http://transportpce/topology">XPDR1-CLIENT1</associated-connection-map-port>
</termination-point>
+ <node-type xmlns="http://org/openroadm/common/network">XPONDER</node-type>
<supporting-node>
<network-ref>openroadm-network</network-ref>
<node-ref>XPDRC01</node-ref>
</supporting-node>
- <node-type xmlns="http://org/openroadm/common/network">XPONDER</node-type>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeC</node-ref>
+ </supporting-node>
</node>
<node>
<node-id>ROADMA01-DEG1</node-id>
<tp-id>DEG1-TTP-TXRX</tp-id>
<tp-type xmlns="http://org/openroadm/common/network">DEGREE-TXRX-TTP</tp-type>
</termination-point>
+ <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
<supporting-node>
<network-ref>openroadm-network</network-ref>
<node-ref>ROADMA01</node-ref>
</supporting-node>
- <node-type xmlns="http://org/openroadm/common/network">DEGREE</node-type>
+ <supporting-node>
+ <network-ref>clli-network</network-ref>
+ <node-ref>NodeA</node-ref>
+ </supporting-node>
<degree-attributes xmlns="http://org/openroadm/network/topology">
<degree-number>1</degree-number>
<available-wavelengths>
},
"service-a-end": {
"node-id": "XPDRA01",
- "service-rate": "0",
+ "service-rate": "100",
+ "service-format": "Ethernet",
"clli": "nodeA"
},
"service-z-end": {
"node-id": "XPDRC01",
- "service-rate": "0",
+ "service-rate": "100",
+ "service-format": "Ethernet",
"clli": "nodeC"
}
}
},
"service-a-end": {
"node-id": "ROADMA01",
- "service-rate": "0",
- "clli": "nodeA"
+ "service-rate": "100",
+ "service-format": "Ethernet",
+ "clli": "NodeA"
},
"service-z-end": {
"node-id": "ROADMC01",
- "service-rate": "0",
- "clli": "nodeC"
+ "service-rate": "100",
+ "service-format": "Ethernet",
+ "clli": "NodeC"
}
}
}
},
"service-a-end": {
"node-id": "XPONDER-1-2",
- "service-rate": "0",
+ "service-rate": "100",
+ "service-format": "Ethernet",
"clli": "ORANGE1"
},
"service-z-end": {
"node-id": "XPONDER-3-2",
- "service-rate": "0",
- "clli": "ORANGE1"
+ "service-rate": "100",
+ "service-format": "Ethernet",
+ "clli": "ORANGE3"
}
}
}
"request-id": "request1"
},
"service-a-end": {
- "service-rate": "0",
+ "service-rate": "100",
+ "service-format": "Ethernet",
"clli": "cll21",
"node-id": "OpenROADM-2-1"
},
"service-z-end": {
- "service-rate": "0",
+ "service-rate": "100",
+ "service-format": "Ethernet",
"clli": "ncli22",
"node-id": "OpenROADM-2-2"
},
},
"service-a-end": {
"service-format": "Ethernet",
- "service-rate": "0",
- "clli": "clli11",
+ "service-rate": "100",
+ "clli": "ORANGE2",
"node-id": "XPONDER-2-2",
"tx-direction": {
"port": {
},
"service-z-end": {
"service-format": "Ethernet",
- "service-rate": "0",
- "clli": "clli11",
+ "service-rate": "100",
+ "clli": "ORANGE1",
"node-id": "XPONDER-1-2",
"tx-direction": {
"port": {
"request-id": "request 1"
},
"service-a-end": {
- "service-rate": "0",
- "node-id": "XPONDER-1-2"
+ "service-rate": "100",
+ "service-format": "Ethernet",
+ "node-id": "XPONDER-1-2",
+ "clli": "ORANGE1"
},
"service-z-end": {
- "service-rate": "0",
- "node-id": "XPONDER-3-2"
+ "service-rate": "100",
+ "service-format": "Ethernet",
+ "node-id": "XPONDER-3-2",
+ "clli": "ORANGE3"
},
"pce-metric": "hop-count"
}
"request-id": "request 1"
},
"service-a-end": {
- "service-rate": "0",
- "node-id": "XPONDER-1-2"
+ "service-rate": "100",
+ "service-format": "Ethernet",
+ "node-id": "XPONDER-1-2",
+ "clli": "ORANGE1"
},
"service-z-end": {
- "service-rate": "0",
- "node-id": "XPONDER-3-2"
+ "service-rate": "100",
+ "service-format": "Ethernet",
+ "node-id": "XPONDER-3-2",
+ "clli": "ORANGE3"
},
"hard-constraints": {
"exclude_": {