Update transportpce-topology enums
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / networkanalyzer / PceLink.java
1 /*
2  * Copyright © 2017 AT&T, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.transportpce.pce.networkanalyzer;
10
11 import java.io.Serializable;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import java.util.List;
15 import java.util.Map;
16 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1;
17 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
18 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
19 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev200529.span.attributes.LinkConcatenation;
20 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev200529.span.attributes.LinkConcatenation.FiberType;
21 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev200529.span.attributes.LinkConcatenationKey;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.link.oms.attributes.Span;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmLinkType;
24 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.OtnLinkType;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 @SuppressWarnings("serial")
33 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
34     value = "SE_NO_SERIALVERSIONID",
35     justification = "https://github.com/rzwitserloot/lombok/wiki/WHY-NOT:-serialVersionUID")
36 public class PceLink implements Serializable {
37
38     /* Logging. */
39     private static final Logger LOG = LoggerFactory.getLogger(PceLink.class);
40     ///////////////////////// LINKS ////////////////////
41     /*
42      * extension of Link to include constraints and Graph weight
43      */
44     double weight = 0;
45     private boolean isValid = true;
46
47     // this member is for XPONDER INPUT/OUTPUT links.
48     // it keeps name of client corresponding to NETWORK TP
49     private String client = "";
50     private final LinkId linkId;
51     private final OpenroadmLinkType linkType;
52     private final NodeId sourceId;
53     private final NodeId destId;
54     private final TpId sourceTP;
55     private final TpId destTP;
56     private final String sourceNetworkSupNodeId;
57     private final String destNetworkSupNodeId;
58     private final String sourceCLLI;
59     private final String destCLLI;
60     private final LinkId oppositeLink;
61     private final AdminStates adminStates;
62     private final State state;
63     private final Long latency;
64     private final Long availableBandwidth;
65     private final Long usedBandwidth;
66     private final List<Long> srlgList;
67     private final double osnr;
68     private final transient Span omsAttributesSpan;
69     //meter per ms
70     private static final double CELERITY = 2.99792458 * 1e5;
71     private static final double NOISE_MASK_A = 0.571429;
72     private static final double NOISE_MASK_B = 39.285714;
73     private static final double UPPER_BOUND_OSNR = 33;
74     private static final double LOWER_BOUND_OSNR = 0.1;
75
76     public PceLink(Link link, PceNode source, PceNode dest) {
77         LOG.info("PceLink: : PceLink start ");
78
79         this.linkId = link.getLinkId();
80
81         this.sourceId = link.getSource().getSourceNode();
82         this.destId = link.getDestination().getDestNode();
83
84         this.sourceTP = link.getSource().getSourceTp();
85         this.destTP = link.getDestination().getDestTp();
86
87         this.sourceNetworkSupNodeId = source.getSupNetworkNodeId();
88         this.destNetworkSupNodeId = dest.getSupNetworkNodeId();
89
90         this.sourceCLLI = source.getSupClliNodeId();
91         this.destCLLI = dest.getSupClliNodeId();
92
93         this.linkType = MapUtils.calcType(link);
94
95         this.oppositeLink = calcOpposite(link);
96
97         this.adminStates = link.augmentation(Link1.class).getAdministrativeState();
98         this.state = link.augmentation(Link1.class).getOperationalState();
99
100         if (this.linkType == OpenroadmLinkType.ROADMTOROADM) {
101             this.omsAttributesSpan = MapUtils.getOmsAttributesSpan(link);
102             this.srlgList = MapUtils.getSRLG(link);
103             this.latency = calcLatency(link);
104             this.osnr = calcSpanOSNR();
105             this.availableBandwidth = 0L;
106             this.usedBandwidth = 0L;
107         } else if (this.linkType == OpenroadmLinkType.OTNLINK) {
108             this.availableBandwidth = MapUtils.getAvailableBandwidth(link);
109             this.usedBandwidth = MapUtils.getUsedBandwidth(link);
110             this.srlgList = MapUtils.getSRLGfromLink(link);
111             this.osnr = 0.0;
112             this.latency = 0L;
113             this.omsAttributesSpan = null;
114         } else {
115             this.omsAttributesSpan = null;
116             this.srlgList = null;
117             this.latency = 0L;
118             //infinite OSNR in DB
119             this.osnr = 100L;
120             this.availableBandwidth = 0L;
121             this.usedBandwidth = 0L;
122         }
123         LOG.debug("PceLink: created PceLink  {}", linkId);
124     }
125
126     //Retrieve the opposite link
127     private LinkId calcOpposite(Link link) {
128         LinkId tmpoppositeLink = MapUtils.extractOppositeLink(link);
129         if (tmpoppositeLink == null) {
130             LOG.error("PceLink: Error calcOpposite. Link is ignored {}", link.getLinkId().getValue());
131             isValid = false;
132         }
133         return tmpoppositeLink;
134     }
135
136     //Compute the link latency : if the latency is not defined, the latency is computed from the omsAttributesSpan
137     private Long calcLatency(Link link) {
138         Link1 link1 = link.augmentation(Link1.class);
139         if (link1.getLinkLatency() != null) {
140             return link1.getLinkLatency().toJava();
141         }
142         if (this.omsAttributesSpan == null) {
143             return 1L;
144         }
145         double tmp = 0;
146         Map<LinkConcatenationKey, LinkConcatenation> linkConcatenationMap = this.omsAttributesSpan
147                 .nonnullLinkConcatenation();
148         for (Map.Entry<LinkConcatenationKey, LinkConcatenation> entry : linkConcatenationMap.entrySet()) {
149             // Length is expressed in meter and latency is expressed in ms according to OpenROADM MSA
150             if (entry == null || entry.getValue() == null || entry.getValue().getSRLGLength() == null) {
151                 LOG.debug("In PceLink: cannot compute the latency for the link {}", link.getLinkId().getValue());
152                 return 1L;
153             }
154             tmp += entry.getValue().getSRLGLength().toJava() / CELERITY;
155             LOG.info("In PceLink: The latency of link {} == {}", link.getLinkId(), tmp);
156         }
157         return (long) Math.ceil(tmp);
158     }
159
160     //Compute the OSNR of a span
161     public double calcSpanOSNR() {
162         if (this.omsAttributesSpan == null) {
163             return 0L;
164         }
165         Collection<LinkConcatenation> linkConcatenationList =
166             this.omsAttributesSpan.nonnullLinkConcatenation().values();
167         if (linkConcatenationList == null) {
168             LOG.error("in PceLink : Null field in the OmsAttrubtesSpan");
169             return 0L;
170         }
171         Iterator<LinkConcatenation> linkConcatenationiterator = linkConcatenationList.iterator();
172         if (!linkConcatenationiterator.hasNext()) {
173             return 0L;
174         }
175         // power on the output of the previous ROADM (dBm)
176         double pout = retrievePower(linkConcatenationiterator.next().getFiberType());
177         // span loss (dB)
178         double spanLoss = this.omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue();
179         // power on the input of the current ROADM (dBm)
180         double pin = pout - spanLoss;
181         double spanOsnrDb = NOISE_MASK_A * pin + NOISE_MASK_B;
182         if (spanOsnrDb > UPPER_BOUND_OSNR) {
183             spanOsnrDb = UPPER_BOUND_OSNR;
184         } else if (spanOsnrDb < LOWER_BOUND_OSNR) {
185             spanOsnrDb = LOWER_BOUND_OSNR;
186         }
187         return spanOsnrDb;
188     }
189
190     private double retrievePower(FiberType fiberType) {
191         double power;
192         switch (fiberType) {
193             case Smf:
194                 power = 2;
195                 break;
196             case Eleaf:
197                 power = 1;
198                 break;
199             case Truewavec:
200                 power = -1;
201                 break;
202             case Oleaf:
203             case Dsf:
204             case Truewave:
205             case NzDsf:
206             case Ull:
207             default:
208                 power = 0;
209                 break;
210         }
211         return power;
212     }
213
214     public LinkId getOppositeLink() {
215         return oppositeLink;
216     }
217
218     public AdminStates getAdminStates() {
219         return adminStates;
220     }
221
222     public State getState() {
223         return state;
224     }
225
226     public TpId getSourceTP() {
227         return sourceTP;
228     }
229
230     public TpId getDestTP() {
231         return destTP;
232     }
233
234     public OpenroadmLinkType getlinkType() {
235         return linkType;
236     }
237
238     public LinkId getLinkId() {
239         return linkId;
240     }
241
242     public NodeId getSourceId() {
243         return sourceId;
244     }
245
246     public NodeId getDestId() {
247         return destId;
248     }
249
250     public String getClient() {
251         return client;
252     }
253
254     public void setClient(String client) {
255         this.client = client;
256     }
257
258     // Double for transformer of JUNG graph
259     public Double getLatency() {
260         return latency.doubleValue();
261     }
262
263     public Long getAvailableBandwidth() {
264         return availableBandwidth;
265     }
266
267     public Long getUsedBandwidth() {
268         return usedBandwidth;
269     }
270
271     public String getsourceNetworkSupNodeId() {
272         return sourceNetworkSupNodeId;
273     }
274
275     public String getdestNetworkSupNodeId() {
276         return destNetworkSupNodeId;
277     }
278
279     public List<Long> getsrlgList() {
280         return srlgList;
281     }
282
283     public double getosnr() {
284         return osnr;
285     }
286
287     public String getsourceCLLI() {
288         return sourceCLLI;
289     }
290
291     public String getdestCLLI() {
292         return destCLLI;
293     }
294
295     public boolean isValid() {
296         if ((this.linkId == null) || (this.linkType == null) || (this.oppositeLink == null)) {
297             isValid = false;
298             LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", linkId);
299         }
300         isValid = checkParams();
301         if ((this.omsAttributesSpan == null) && (this.linkType == OpenroadmLinkType.ROADMTOROADM)) {
302             isValid = false;
303             LOG.error("PceLink: Error reading Span for OMS link. Link is ignored {}", linkId);
304         }
305         if ((this.srlgList != null) && (this.srlgList.isEmpty())) {
306             isValid = false;
307             LOG.error("PceLink: Empty srlgList for OMS link. Link is ignored {}", linkId);
308         }
309         return isValid;
310     }
311
312     public boolean isOtnValid(Link link, String serviceType) {
313
314         if (this.linkType != OpenroadmLinkType.OTNLINK) {
315             LOG.error("PceLink: Not an OTN link. Link is ignored {}", linkId);
316             return false;
317         }
318
319         OtnLinkType otnLinkType = link
320             .augmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1.class)
321             .getOtnLinkType();
322         if (this.availableBandwidth == 0L) {
323             LOG.error("PceLink: No bandwidth available for OTN Link, link {}  is ignored ", linkId);
324             return false;
325         }
326
327         long neededBW;
328         OtnLinkType neededType = null;
329         switch (serviceType) {
330             case "ODUC4":
331                 if (this.usedBandwidth != 0L) {
332                     return false;
333                 }
334                 neededBW = 400000L;
335                 neededType = OtnLinkType.OTUC4;
336                 break;
337             case "ODU4":
338             case "100GEs":
339                 if (this.usedBandwidth != 0L) {
340                     return false;
341                 }
342                 neededBW = 100000L;
343                 neededType = OtnLinkType.OTU4;
344                 break;
345             case "ODU2":
346             case "ODU2e":
347                 neededBW = 12500L;
348                 break;
349             case "ODU0":
350                 neededBW = 1250L;
351                 break;
352             case "ODU1":
353                 neededBW = 2500L;
354                 break;
355             case "100GEm":
356                 neededBW = 100000L;
357                 neededType = OtnLinkType.ODUC4;
358                 break;
359             case "10GE":
360                 neededBW = 10000L;
361                 neededType = OtnLinkType.ODTU4;
362                 break;
363             case "1GE":
364                 neededBW = 1000L;
365                 neededType = OtnLinkType.ODTU4;
366                 break;
367             default:
368                 LOG.error("PceLink: isOtnValid Link {} unsupported serviceType {} ", linkId, serviceType);
369                 return false;
370         }
371
372         if ((this.availableBandwidth >= neededBW)
373             && ((neededType == null) || (neededType.equals(otnLinkType)))) {
374             LOG.info("PceLink: Selected Link {} has available bandwidth and is eligible for {} creation ",
375                 linkId, serviceType);
376         }
377
378         return checkParams();
379     }
380
381     private boolean checkParams() {
382         if ((this.linkId == null) || (this.linkType == null) || (this.oppositeLink == null)) {
383             LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", linkId);
384             return false;
385         }
386         if ((this.adminStates == null) || (this.state == null)) {
387             LOG.error("PceLink: Link is not available. Link is ignored {}", linkId);
388             return false;
389         }
390         if ((this.sourceId == null) || (this.destId == null) || (this.sourceTP == null) || (this.destTP == null)) {
391             LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", linkId);
392             return false;
393         }
394         if ((this.sourceNetworkSupNodeId.equals("")) || (this.destNetworkSupNodeId.equals(""))) {
395             LOG.error("PceLink: No Link source SuppNodeID or destination SuppNodeID is available. Link is ignored {}",
396                 linkId);
397             return false;
398         }
399         if ((this.sourceCLLI.equals("")) || (this.destCLLI.equals(""))) {
400             LOG.error("PceLink: No Link source CLLI or destination CLLI is available. Link is ignored {}", linkId);
401             return false;
402         }
403
404         return true;
405     }
406
407     @Override
408     public String toString() {
409         return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latency=" + latency;
410     }
411 }