Adapt PCE to compute a 100GE path on OTN Switch
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / PcePathDescription.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 package org.opendaylight.transportpce.pce;
9
10 import com.google.common.collect.ImmutableList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14 import org.opendaylight.transportpce.common.ResponseCodes;
15 import org.opendaylight.transportpce.common.StringConstants;
16 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
17 import org.opendaylight.transportpce.pce.networkanalyzer.PceLink;
18 import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
19 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.FrequencyTHz;
20 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
21 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.ModulationFormat;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.OpucnTribSlotDef;
23 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirectionBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirectionBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZBuilder;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZKey;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToA;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToABuilder;
30 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToAKey;
31 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.Resource;
32 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.ResourceBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.LinkBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.NodeBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPoint;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPointBuilder;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
38 import org.opendaylight.yangtools.yang.common.Uint32;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 public class PcePathDescription {
43     /* Logging. */
44     private static final Logger LOG = LoggerFactory.getLogger(PcePathDescription.class);
45
46     private List<PceLink> pathAtoZ = null;
47     private PceResult rc;
48     private Map<LinkId, PceLink> allPceLinks = null;
49
50     public PcePathDescription(List<PceLink> pathAtoZ, Map<LinkId, PceLink> allPceLinks, PceResult rc) {
51         super();
52         this.allPceLinks = allPceLinks;
53         this.pathAtoZ = pathAtoZ;
54         this.rc = rc;
55     }
56
57     public PceResult buildDescriptions() {
58         LOG.info("In buildDescriptions: AtoZ =  {}", pathAtoZ);
59         Map<AToZKey,AToZ> atozMap = new HashMap<>();
60         if (pathAtoZ == null) {
61             rc.setRC(ResponseCodes.RESPONSE_FAILED);
62             LOG.error("In buildDescriptions: there is empty AtoZ path");
63             return rc;
64         }
65
66         buildAtoZ(atozMap, pathAtoZ);
67         rc.setAtoZDirection(buildAtoZDirection(atozMap).build());
68         List<PceLink> pathZtoA = ImmutableList.copyOf(pathAtoZ).reverse();
69         LOG.info("In buildDescriptions: ZtoA {}", pathZtoA);
70
71         Map<ZToAKey,ZToA> ztoaMap = new HashMap<>();
72         if (pathZtoA == null) {
73             rc.setRC(ResponseCodes.RESPONSE_FAILED);
74             LOG.error("In buildDescriptions: there is empty ZtoA path");
75             return rc;
76         }
77         buildZtoA(ztoaMap, pathZtoA);
78         rc.setZtoADirection(buildZtoADirection(ztoaMap).build());
79
80         return rc;
81     }
82
83     /**
84      * Create a builder for AtoZDirection object.
85      * @param atozMap Map of AToZ object
86      * @return a builder for AtoZDirection object
87      */
88     private AToZDirectionBuilder buildAtoZDirection(Map<AToZKey, AToZ> atozMap) {
89         AToZDirectionBuilder atoZDirectionBldr = new AToZDirectionBuilder()
90             .setRate(Uint32.valueOf(rc.getRate()))
91             .setModulationFormat(GridConstant.RATE_MODULATION_FORMAT_MAP
92                     .getOrDefault(Uint32.valueOf(rc.getRate()), ModulationFormat.DpQpsk).getName())
93             .setAToZ(atozMap);
94         switch (rc.getServiceType()) {
95             case StringConstants.SERVICE_TYPE_400GE:
96             case StringConstants.SERVICE_TYPE_OTUC4:
97             case StringConstants.SERVICE_TYPE_100GE_T:
98             case StringConstants.SERVICE_TYPE_OTU4:
99                 atoZDirectionBldr.setAToZMaxFrequency(new FrequencyTHz(rc.getMaxFreq()));
100                 atoZDirectionBldr.setAToZMinFrequency(new FrequencyTHz(rc.getMinFreq()));
101                 atoZDirectionBldr.setAToZWavelengthNumber(Uint32.valueOf(rc.getResultWavelength()));
102                 break;
103             case StringConstants.SERVICE_TYPE_100GE_M:
104             case StringConstants.SERVICE_TYPE_100GE_S:
105             case StringConstants.SERVICE_TYPE_10GE:
106             case StringConstants.SERVICE_TYPE_1GE:
107             case StringConstants.SERVICE_TYPE_ODU4:
108             case StringConstants.SERVICE_TYPE_ODUC4:
109                 if (rc.getResultTribPortTribSlot() != null && rc.getResultTribPortTribSlot().get(0) != null
110                     && rc.getResultTribPortTribSlot().get(1) != null) {
111                     atoZDirectionBldr.setAToZWavelengthNumber(Uint32.valueOf(0))
112                             .setMinTribSlot(rc.getResultTribPortTribSlot().get(0))
113                             .setMaxTribSlot(rc.getResultTribPortTribSlot().get(1));
114                 } else {
115                     LOG.warn("Trib port and trib slot number should be present");
116                     atoZDirectionBldr.setMinTribSlot(new OpucnTribSlotDef("0.0"))
117                         .setMaxTribSlot(new OpucnTribSlotDef("0.0"));
118                 }
119                 break;
120             default:
121                 LOG.warn("unknown service type : unable to set Min/Max frequencies or trib-port/trib-slot");
122                 break;
123         }
124         return atoZDirectionBldr;
125     }
126
127     /**
128      * Create a builder for ZtoADirection object.
129      * @param ztoaMap Map of ZToA object
130      * @return a builder for ZtoADirection object
131      */
132     private ZToADirectionBuilder buildZtoADirection(Map<ZToAKey, ZToA> ztoaMap) {
133         ZToADirectionBuilder ztoADirectionBldr = new ZToADirectionBuilder().setRate(Uint32.valueOf(rc.getRate()))
134                 .setModulationFormat(GridConstant.RATE_MODULATION_FORMAT_MAP
135                         .getOrDefault(Uint32.valueOf(rc.getRate()), ModulationFormat.DpQpsk).getName())
136                 .setZToA(ztoaMap);
137         switch (rc.getServiceType()) {
138             case StringConstants.SERVICE_TYPE_400GE:
139             case StringConstants.SERVICE_TYPE_OTUC4:
140             case StringConstants.SERVICE_TYPE_100GE_T:
141             case StringConstants.SERVICE_TYPE_OTU4:
142                 ztoADirectionBldr.setZToAMaxFrequency(new FrequencyTHz(rc.getMaxFreq()));
143                 ztoADirectionBldr.setZToAMinFrequency(new FrequencyTHz(rc.getMinFreq()));
144                 ztoADirectionBldr.setZToAWavelengthNumber(Uint32.valueOf(rc.getResultWavelength()));
145                 break;
146             case StringConstants.SERVICE_TYPE_100GE_M:
147             case StringConstants.SERVICE_TYPE_100GE_S:
148             case StringConstants.SERVICE_TYPE_10GE:
149             case StringConstants.SERVICE_TYPE_1GE:
150             case StringConstants.SERVICE_TYPE_ODU4:
151                 if (rc.getResultTribPortTribSlot() != null && rc.getResultTribPortTribSlot().get(0) != null
152                     && rc.getResultTribPortTribSlot().get(1) != null) {
153                     ztoADirectionBldr.setZToAWavelengthNumber(Uint32.valueOf(0))
154                             .setMinTribSlot(rc.getResultTribPortTribSlot().get(0))
155                             .setMaxTribSlot(rc.getResultTribPortTribSlot().get(1));
156                 } else {
157                     LOG.warn("Trib port and trib slot number should be present");
158                     ztoADirectionBldr.setMinTribSlot(new OpucnTribSlotDef("0.0"))
159                         .setMaxTribSlot(new OpucnTribSlotDef("0.0"));
160                 }
161                 break;
162             default:
163                 LOG.warn("unknown service type : unable to set Min/Max frequencies");
164                 break;
165         }
166         return ztoADirectionBldr;
167     }
168
169     @SuppressWarnings("java:S138")
170     //sonar issue This method has 77 lines, which is greater than the 75 lines authorized. Split it into smaller
171     //ignore as it's not relevant to split it from functional point
172     private void buildAtoZ(Map<AToZKey, AToZ> atozMap, List<PceLink> path) {
173         Integer index = 0;
174         PceLink lastLink = null;
175         AToZ lastResource = null;
176
177         // build A side Client TP
178         String tpName = path.get(0).getClient();
179         String xname = path.get(0).getSourceId().getValue();
180         TerminationPoint stp = new TerminationPointBuilder()
181                 .setTpId(tpName).setTpNodeId(xname)
182                 .build();
183
184         AToZKey clientKey = new AToZKey(index.toString());
185         Resource clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
186         AToZ firstResource = new AToZBuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
187         atozMap.put(firstResource.key(),firstResource);
188         index += 1;
189         for (PceLink pcelink : path) {
190             String srcName = pcelink.getSourceId().getValue();
191             // Nodes
192             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce
193                 .resource.resource.resource.Node sourceNode = new NodeBuilder()
194                 .setNodeId(srcName)
195                 .build();
196
197             // Source Resource
198             AToZKey sourceKey = new AToZKey(index.toString());
199             Resource nodeResource1 = new ResourceBuilder().setResource(sourceNode).setState(State.InService).build();
200             AToZ srcResource = new AToZBuilder().setId(srcName).withKey(sourceKey).setResource(nodeResource1).build();
201             index += 1;
202             atozMap.put(srcResource.key(),srcResource);
203
204             // source TP
205             tpName = pcelink.getSourceTP().getValue();
206             stp = new TerminationPointBuilder()
207                     .setTpNodeId(srcName).setTpId(tpName)
208                     .build();
209
210             // Resource
211             AToZKey srcTPKey = new AToZKey(index.toString());
212             Resource tpResource1 = new ResourceBuilder().setResource(stp).setState(State.InService).build();
213             AToZ stpResource = new AToZBuilder().setId(tpName).withKey(srcTPKey).setResource(tpResource1).build();
214             index += 1;
215             atozMap.put(stpResource.key(),stpResource);
216
217             String linkName = pcelink.getLinkId().getValue();
218             // Link
219             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce
220                 .resource.resource.resource.Link atozLink = new LinkBuilder()
221                 .setLinkId(linkName)
222                 .build();
223
224             // Link Resource
225             AToZKey linkKey = new AToZKey(index.toString());
226             Resource nodeResource2 = new ResourceBuilder().setResource(atozLink).setState(pcelink.getState()).build();
227             AToZ linkResource = new AToZBuilder().setId(linkName).withKey(linkKey).setResource(nodeResource2).build();
228             index += 1;
229             atozMap.put(linkResource.key(),linkResource);
230
231             String destName = pcelink.getDestId().getValue();
232             // target TP
233             tpName = pcelink.getDestTP().getValue();
234             TerminationPoint dtp = new TerminationPointBuilder()
235                 .setTpNodeId(destName).setTpId(tpName)
236                 .build();
237
238             // Resource
239             AToZKey destTPKey = new AToZKey(index.toString());
240             Resource tpResource2 = new ResourceBuilder().setResource(dtp).setState(State.InService).build();
241             AToZ ttpResource = new AToZBuilder().setId(tpName).withKey(destTPKey).setResource(tpResource2).build();
242             index += 1;
243             atozMap.put(ttpResource.key(),ttpResource);
244
245             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce
246                 .resource.resource.resource.Node targetNode = new NodeBuilder()
247                 .setNodeId(destName)
248                 .build();
249
250             // Target Resource
251             AToZKey targetKey = new AToZKey(index.toString());
252             Resource nodeResource3 = new ResourceBuilder().setResource(targetNode).setState(State.InService).build();
253             lastResource = new AToZBuilder().setId(destName).withKey(targetKey).setResource(nodeResource3).build();
254
255             lastLink = pcelink;
256         }
257
258         if (lastResource != null) {
259             atozMap.put(lastResource.key(),lastResource);
260         }
261
262         // build Z side Client TP
263         tpName = lastLink.getClient();
264         xname = lastLink.getDestId().getValue();
265         stp = new TerminationPointBuilder()
266                 .setTpNodeId(xname).setTpId(tpName)
267                 .build();
268
269         index += 1;
270         clientKey = new AToZKey(index.toString());
271         clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
272         lastResource = new AToZBuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
273         atozMap.put(lastResource.key(),lastResource);
274
275     }
276
277     private void buildZtoA(Map<ZToAKey, ZToA> ztoaList, List<PceLink> path) {
278         Integer index = 0;
279         PceLink lastLink = null;
280         ZToA lastResource = null;
281
282         // build Z size Client TP
283         PceLink pcelink = this.allPceLinks.get(path.get(0).getOppositeLink());
284         String tpName = pcelink.getClient();
285         String xname = pcelink.getSourceId().getValue();
286         TerminationPoint stp = new TerminationPointBuilder()
287                 .setTpNodeId(xname).setTpId(tpName)
288                 .build();
289
290         ZToAKey clientKey = new ZToAKey(index.toString());
291         Resource clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
292         ZToA firstResource = new ZToABuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
293         ztoaList.put(firstResource.key(),firstResource);
294         index += 1;
295
296         for (PceLink pcelinkAtoZ : path) {
297
298             pcelink = this.allPceLinks.get(pcelinkAtoZ.getOppositeLink());
299             LOG.debug("link to oppsite: {} to {}", pcelinkAtoZ, pcelink);
300
301             String srcName = pcelink.getSourceId().getValue();
302
303
304             // Nodes
305             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce
306                 .resource.resource.resource.Node sourceNode = new NodeBuilder()
307                 .setNodeId(srcName).build();
308
309
310             // Source Resource
311             ZToAKey sourceKey = new ZToAKey(index.toString());
312             Resource nodeResource1 = new ResourceBuilder().setResource(sourceNode).setState(State.InService).build();
313             ZToA srcResource = new ZToABuilder().setId(srcName).withKey(sourceKey).setResource(nodeResource1).build();
314             index += 1;
315             ztoaList.put(srcResource.key(),srcResource);
316
317             // source TP
318             tpName = pcelink.getSourceTP().getValue();
319             stp = new TerminationPointBuilder()
320                     .setTpNodeId(srcName).setTpId(tpName)
321                     .build();
322
323             // Resource
324             ZToAKey srcTPKey = new ZToAKey(index.toString());
325             Resource tpResource1 = new ResourceBuilder().setResource(stp).setState(State.InService).build();
326             ZToA stpResource = new ZToABuilder().setId(tpName).withKey(srcTPKey).setResource(tpResource1).build();
327             index += 1;
328             ztoaList.put(stpResource.key(),stpResource);
329
330             String linkName = pcelink.getLinkId().getValue();
331             // Link
332             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce
333                 .resource.resource.resource.Link ztoaLink = new LinkBuilder()
334                 .setLinkId(linkName).build();
335
336             // Link Resource
337             ZToAKey linkKey = new ZToAKey(index.toString());
338             Resource nodeResource2 = new ResourceBuilder().setResource(ztoaLink).setState(State.InService).build();
339             ZToA linkResource = new ZToABuilder().setId(linkName).withKey(linkKey).setResource(nodeResource2).build();
340             index += 1;
341             ztoaList.put(linkResource.key(),linkResource);
342
343             String destName = pcelink.getDestId().getValue();
344             // target TP
345             tpName = pcelink.getDestTP().getValue();
346             TerminationPoint ttp = new TerminationPointBuilder()
347                     .setTpNodeId(destName).setTpId(tpName).build();
348
349             // Resource
350             ZToAKey destTPKey = new ZToAKey(index.toString());
351             Resource tpResource2 = new ResourceBuilder().setResource(ttp).setState(State.InService).build();
352             ZToA ttpResource = new ZToABuilder().setId(tpName).withKey(destTPKey).setResource(tpResource2).build();
353             index += 1;
354             ztoaList.put(ttpResource.key(),ttpResource);
355
356
357             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce
358                 .resource.resource.resource.Node targetNode = new NodeBuilder()
359                 .setNodeId(destName).build();
360             // Target Resource
361             ZToAKey targetKey = new ZToAKey(index.toString());
362             Resource nodeResource3 = new ResourceBuilder().setResource(targetNode).setState(State.InService).build();
363             lastResource = new ZToABuilder().setId(destName).withKey(targetKey).setResource(nodeResource3).build();
364
365             lastLink = pcelink;
366         }
367         if (lastResource != null) {
368             ztoaList.put(lastResource.key(),lastResource);
369         }
370
371         // build Z side Client TP
372         tpName = lastLink.getClient();
373         xname = lastLink.getDestId().getValue();
374         stp = new TerminationPointBuilder()
375                 .setTpNodeId(xname).setTpId(tpName).build();
376
377         index += 1;
378         clientKey = new ZToAKey(index.toString());
379         clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
380         lastResource = new ZToABuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
381         ztoaList.put(lastResource.key(),lastResource);
382     }
383
384     public PceResult getReturnStructure() {
385         return rc;
386     }
387 }