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