2 * Copyright © 2017 AT&T, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.transportpce.pce.graph;
11 import java.util.ArrayList;
12 import java.util.List;
15 import org.jgrapht.GraphPath;
16 import org.opendaylight.transportpce.common.ResponseCodes;
17 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
18 import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
19 import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
20 import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
21 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 public class PostAlgoPathValidator {
28 private static final Logger LOG = LoggerFactory.getLogger(PceGraph.class);
31 private static final int MAX_WAWELENGTH = 96;
32 private static final double MIN_OSNR_W100G = 17;
33 private static final double TRX_OSNR = 33;
34 private static final double ADD_OSNR = 30;
35 public static final Long CONST_OSNR = 1L;
36 public static final double SYS_MARGIN = 0;
38 public PceResult checkPath(GraphPath<String, PceGraphEdge> path,
39 Map<NodeId, PceNode> allPceNodes, PceResult pceResult, PceConstraints pceHardConstraints) {
41 //check if the path is empty
42 if (path.getEdgeList().size() == 0) {
43 pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
47 //Choose wavelength available in all nodes of the path
48 Long waveL = chooseWavelength(path, allPceNodes);
50 pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
51 pceResult.setLocalCause(PceResult.LocalCause.NO_PATH_EXISTS);
54 pceResult.setResultWavelength(waveL);
55 LOG.info("In PostAlgoPathValidator: chooseWavelength WL found {} {}", waveL, path.toString());
57 // TODO here other post algo validations can be added
58 // more data can be sent to PceGraph module via PceResult structure if required
61 if (!checkOSNR(path)) {
62 pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
63 pceResult.setLocalCause(PceResult.LocalCause.OUT_OF_SPEC_OSNR);
67 //Check if MaxLatency is defined in the hard constraints
68 if (pceHardConstraints.getMaxLatency() != -1) {
69 if (!checkLatency(pceHardConstraints.getMaxLatency(), path)) {
70 pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
71 pceResult.setLocalCause(PceResult.LocalCause.TOO_HIGH_LATENCY);
76 //Check if nodes are included in the hard constraints
77 if (!checkInclude(path, pceHardConstraints)) {
78 pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
79 pceResult.setLocalCause(PceResult.LocalCause.HD_NODE_INCLUDE);
83 pceResult.setRC(ResponseCodes.RESPONSE_OK);
87 //Choose the first available wavelength from the source to the destination
88 private Long chooseWavelength(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
89 Long wavelength = -1L;
91 for (long i = 1; i <= MAX_WAWELENGTH; i++) {
92 boolean completed = true;
93 LOG.debug("In chooseWavelength: {} {}", path.getLength(), path.toString());
94 for (PceGraphEdge edge : path.getEdgeList()) {
95 LOG.debug("In chooseWavelength: source {} ", edge.link().getSourceId().toString());
96 PceNode pceNode = allPceNodes.get(edge.link().getSourceId());
97 if (!pceNode.checkWL(i)) {
111 private boolean checkLatency(Long maxLatency, GraphPath<String, PceGraphEdge> path) {
114 for (PceGraphEdge edge : path.getEdgeList()) {
116 latency += edge.link().getLatency();
117 LOG.debug("- In checkLatency: latency of {} = {} units", edge.link().getLinkId().getValue(),latency);
118 } catch (NullPointerException e) {
119 LOG.warn("- In checkLatency: the link {} does not contain latency field",
120 edge.link().getLinkId().getValue());
123 if (latency > maxLatency) {
129 //Check the inclusion if it is defined in the hard constraints
130 private boolean checkInclude(GraphPath<String, PceGraphEdge> path, PceConstraints pceHardConstraintsInput) {
131 List<ResourcePair> listToInclude = pceHardConstraintsInput.getListToInclude();
132 if (listToInclude.isEmpty()) {
136 List<PceGraphEdge> pathEdges = path.getEdgeList();
137 LOG.debug(" in checkInclude vertex list: [{}]", path.getVertexList());
139 List<String> listOfElementsSubNode = new ArrayList<String>();
140 listOfElementsSubNode.add(pathEdges.get(0).link().getsourceSupNodeId());
141 listOfElementsSubNode.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.NODE,
142 pceHardConstraintsInput));
144 List<String> listOfElementsCLLI = new ArrayList<String>();
145 listOfElementsCLLI.add(pathEdges.get(0).link().getsourceCLLI());
146 listOfElementsCLLI.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.CLLI,
147 pceHardConstraintsInput));
149 List<String> listOfElementsSRLG = new ArrayList<String>();
150 // first link is XPONDEROUTPUT, no SRLG for it
151 listOfElementsSRLG.add("NONE");
152 listOfElementsSRLG.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.SRLG,
153 pceHardConstraintsInput));
155 // validation: check each type for each element
156 for (ResourcePair next : listToInclude) {
158 switch (next.getType()) {
160 if (listOfElementsSubNode.contains(next.getName())) {
161 indx = listOfElementsSubNode.indexOf(next.getName());
165 if (listOfElementsSRLG.contains(next.getName())) {
166 indx = listOfElementsSRLG.indexOf(next.getName());
170 if (listOfElementsCLLI.contains(next.getName())) {
171 indx = listOfElementsCLLI.indexOf(next.getName());
175 LOG.warn(" in checkInclude vertex list unsupported resource type: [{}]", next.getType());
179 LOG.debug(" in checkInclude stopped : {} ", next.getName());
183 LOG.debug(" in checkInclude next found {} in {}", next.getName(), path.getVertexList());
185 listOfElementsSubNode.subList(0, indx).clear();
186 listOfElementsCLLI.subList(0, indx).clear();
187 listOfElementsSRLG.subList(0, indx).clear();
190 LOG.info(" in checkInclude passed : {} ", path.getVertexList());
194 private List<String> listOfElementsBuild(List<PceGraphEdge> pathEdges, PceConstraints.ResourceType type,
195 PceConstraints pceHardConstraints) {
197 List<String> listOfElements = new ArrayList<String>();
198 for (PceGraphEdge link: pathEdges) {
201 listOfElements.add(link.link().getdestSupNodeId());
204 listOfElements.add(link.link().getdestCLLI());
207 if (link.link().getlinkType() != OpenroadmLinkType.ROADMTOROADM) {
208 listOfElements.add("NONE");
212 // srlg of link is List<Long>. But in this algo we need string representation of one SRLG
213 // this should be any SRLG mentioned in include constraints if any of them if mentioned
214 boolean found = false;
215 for (Long srlg : link.link().getsrlgList()) {
216 String srlgStr = String.valueOf(srlg);
217 if (pceHardConstraints.getSRLGnames().contains(srlgStr)) {
218 listOfElements.add(srlgStr);
219 LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link().toString());
225 // there is no specific srlg to include. thus add to list just the first one
226 listOfElements.add("NONE");
230 LOG.debug("listOfElementsBuild unsupported resource type");
233 return listOfElements;
236 //Check the path OSNR
237 private boolean checkOSNR(GraphPath<String, PceGraphEdge> path) {
240 LOG.info("- In checkOSNR: OSNR of the transmitter = {} dB", TRX_OSNR);
241 LOG.info("- In checkOSNR: add-path incremental OSNR = {} dB", ADD_OSNR);
242 double inverseLocalOsnr = getInverseOsnrLinkLu(TRX_OSNR) + getInverseOsnrLinkLu(ADD_OSNR);
243 for (PceGraphEdge edge : path.getEdgeList()) {
244 if (edge.link().getlinkType() == OpenroadmLinkType.ROADMTOROADM) {
246 linkOsnrDb = edge.link().getosnr();
247 LOG.info("- In checkOSNR: OSNR of {} = {} dB", edge.link().getLinkId().getValue(), linkOsnrDb);
248 // 1 over the local OSNR, in linear units
249 inverseLocalOsnr += getInverseOsnrLinkLu(linkOsnrDb);
253 osnrDb = getOsnrDb(1 / inverseLocalOsnr);
255 catch (ArithmeticException e) {
256 LOG.debug("In checkOSNR: OSNR is equal to 0 and the number of links is: {}", path.getEdgeList().size());
259 LOG.info("In checkOSNR: OSNR of the path is {} dB", osnrDb);
260 if ((osnrDb + SYS_MARGIN) < MIN_OSNR_W100G) {
266 private double getOsnrDb(double osnrLu) {
268 osnrDb = 10 * Math.log10(osnrLu);
272 private double getInverseOsnrLinkLu(double linkOsnrDb) {
273 // 1 over the link OSNR, in linear units
275 linkOsnrLu = Math.pow(10, (linkOsnrDb / 10.0));
276 LOG.debug("In retrieveosnr: the inverse of link osnr is {} (Linear Unit)", linkOsnrLu);
277 return (CONST_OSNR / linkOsnrLu);