added OSNR calculation logic into PCE
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / 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;
10
11 import java.util.List;
12 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Link1;
13 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.link.oms.attributes.Span;
14 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev170929.OpenroadmLinkType;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NodeId;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.LinkId;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.Link;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 public class PceLink {
22
23     /* Logging. */
24     private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
25
26     ///////////////////////// LINKS ////////////////////
27     /*
28      * extension of Link to include constraints and Graph weight
29      */
30     // double capacity = 1;
31
32     double weight = 0;
33
34     private boolean isValid = 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
40     private final LinkId linkId;
41     private final OpenroadmLinkType linkType;
42     private final NodeId sourceId;
43     private final NodeId destId;
44     private final Object sourceTP;
45     private final Object destTP;
46     private final LinkId oppositeLink;
47     private final Long latency;
48     private final List<Long> srlg;
49     private final double osnr;
50     private final Span omsAttributesSpan;
51
52     public PceLink(Link link) {
53         LOG.debug("PceLink: : PceLink start ");
54
55         this.linkId = link.getLinkId();
56
57         this.sourceId = link.getSource().getSourceNode();
58         this.destId = link.getDestination().getDestNode();
59
60         this.sourceTP = link.getSource().getSourceTp();
61         this.destTP = link.getDestination().getDestTp();
62
63         this.linkType = calcType(link);
64
65         this.oppositeLink = calcOpposite(link);
66         this.latency = calcLatency(link);
67
68         if (this.linkType == OpenroadmLinkType.ROADMTOROADM) {
69             this.omsAttributesSpan = MapUtils.getOmsAttributesSpan(link);
70             this.srlg = MapUtils.getSRLG(link);
71             this.osnr = retrieveOSNR();
72         } else {
73             this.omsAttributesSpan = null;
74             this.srlg = null;
75             this.osnr = 0L;
76         }
77
78         LOG.debug("PceLink: created PceLink  {}", toString());
79     }
80
81     private OpenroadmLinkType calcType(Link link) {
82         Link1 link1 = null;
83         OpenroadmLinkType tmplType = null;
84
85         // ID and type
86         link1 = link.augmentation(Link1.class);
87         if (link1 == null) {
88             this.isValid = false;
89             LOG.error("PceLink: No Link augmentation available. Link is ignored {}", this.linkId);
90             return null;
91         }
92
93         tmplType = link1.getLinkType();
94         if (tmplType == null) {
95             this.isValid = false;
96             LOG.error("PceLink: No Link type available. Link is ignored {}", this.linkId);
97             return null;
98         }
99         return tmplType;
100     }
101
102     private LinkId calcOpposite(Link link) {
103         // opposite link
104         LinkId tmpoppositeLink = null;
105         org.opendaylight.yang.gen.v1.http.org.openroadm.opposite.links.rev170929.Link1 linkOpposite = link
106             .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.opposite.links.rev170929.Link1.class);
107         tmpoppositeLink = linkOpposite.getOppositeLink();
108         LOG.debug("PceLink: reading oppositeLink.  {}", linkOpposite.toString());
109         if (tmpoppositeLink == null) {
110             this.isValid = false;
111             LOG.error("PceLink: Error reading oppositeLink. Link is ignored {}", this.linkId);
112             return null;
113         }
114         return tmpoppositeLink;
115     }
116
117     private Long calcLatency(Link link) {
118         Long tmplatency = (long)0;
119         Link1 link1 = null;
120         // latency
121         link1 = link.augmentation(Link1.class);
122         tmplatency = link1.getLinkLatency();
123         if (tmplatency == null) {
124             tmplatency = (long) 0;
125         }
126         return tmplatency;
127
128     }
129
130     @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance")
131     public double retrieveOSNR() {
132         double sum = 0;        // sum of 1 over the span OSNRs (linear units)
133         double linkOsnrDb;     // link OSNR, in dB
134         double linkOsnrLu;     // link OSNR, in dB
135         double spanOsnrDb;     // span OSNR, in dB
136         double spanOsnrLu;     // span OSNR, in linear units
137         double ampNoise = 5.5; // default amplifier noise value, in dB
138         double loss;           // fiber span measured loss, in dB
139         double power;          // launch power, in dB
140         double constantA = 38.97293;
141         double constantB = 0.72782;
142         double constantC = -0.532331;
143         double constactD = -0.019549;
144         double upperBoundOSNR = 33;
145         double lowerBoundOSNR = 0.1;
146
147         if (omsAttributesSpan ==  null) {
148             return 0L; // indicates no data or N/A
149         }
150         loss = omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue();
151         switch (omsAttributesSpan.getLinkConcatenation().get(0).getFiberType()) {
152             case Smf:
153                 power = 2;
154                 break;
155
156             case Eleaf:
157                 power = 1;
158                 break;
159
160             case Oleaf:
161                 power = 0;
162                 break;
163
164             case Dsf:
165                 power = 0;
166                 break;
167
168             case Truewave:
169                 power = 0;
170                 break;
171
172             case Truewavec:
173                 power = -1;
174                 break;
175
176             case NzDsf:
177                 power = 0;
178                 break;
179
180             case Ull:
181                 power = 0;
182                 break;
183
184             default:
185                 power = 0;
186                 break;
187         }
188         spanOsnrDb = constantA + constantB * power + constantC * loss + constactD * power * loss;
189         if (spanOsnrDb > upperBoundOSNR) {
190             spanOsnrDb =  upperBoundOSNR;
191         } else if (spanOsnrDb < lowerBoundOSNR) {
192             spanOsnrDb = lowerBoundOSNR;
193         }
194         spanOsnrLu = Math.pow(10, (spanOsnrDb / 10.0));
195         sum = PceConstraints.constOSNR / spanOsnrLu;
196         linkOsnrLu = sum;
197         //link_OSNR_dB = 10 * Math.log10(1 / sum);
198         LOG.debug("In retrieveOSNR: link OSNR is {} dB", linkOsnrLu);
199         return linkOsnrLu;
200     }
201
202
203     public LinkId getOppositeLink() {
204         return this.oppositeLink;
205     }
206
207     public Object getSourceTP() {
208         return this.sourceTP;
209     }
210
211     public Object getDestTP() {
212         return this.destTP;
213     }
214
215     public OpenroadmLinkType getLinkType() {
216         return this.linkType;
217     }
218
219     public LinkId getLinkId() {
220         return this.linkId;
221     }
222
223     public NodeId getSourceId() {
224         return this.sourceId;
225     }
226
227     public NodeId getDestId() {
228         return this.destId;
229     }
230
231     public String getClient() {
232         return this.client;
233     }
234
235     public void setClient(String client) {
236         this.client = client;
237     }
238
239     // Double for transformer of JUNG graph
240     public Double getLatency() {
241         return this.latency.doubleValue();
242     }
243
244     public boolean isValid() {
245         if ((this.linkId == null) || (this.linkType == null) || (this.oppositeLink == null)) {
246             this.isValid = false;
247             LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", this.linkId);
248         }
249         if ((this.sourceId == null) || (this.destId == null) || (this.sourceTP == null) || (this.destTP == null)) {
250             this.isValid = false;
251             LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", this.linkId);
252         }
253
254         return this.isValid;
255     }
256
257     @Override
258     public String toString() {
259         return "PceLink type=" + this.linkType + " ID=" + this.linkId.toString() + " latecy=" + this.latency;
260     }
261
262 }