Adapt PCE to compute a 400GE path
[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.transportpce.b.c._interface.pathdescription.rev201210.path.description.AToZDirectionBuilder;
23 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ZToADirectionBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZ;
25 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZBuilder;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZKey;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ztoa.direction.ZToA;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ztoa.direction.ZToABuilder;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ztoa.direction.ZToAKey;
30 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.Resource;
31 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.ResourceBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.LinkBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.NodeBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.TerminationPoint;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.TerminationPointBuilder;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
37 import org.opendaylight.yangtools.yang.common.Uint16;
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_100GE:
97             case StringConstants.SERVICE_TYPE_OTU4:
98                 atoZDirectionBldr.setAToZMaxFrequency(new FrequencyTHz(rc.getMaxFreq()));
99                 atoZDirectionBldr.setAToZMinFrequency(new FrequencyTHz(rc.getMinFreq()));
100                 atoZDirectionBldr.setAToZWavelengthNumber(Uint32.valueOf(rc.getResultWavelength()));
101                 break;
102             case StringConstants.SERVICE_TYPE_10GE:
103             case StringConstants.SERVICE_TYPE_1GE:
104             case StringConstants.SERVICE_TYPE_ODU4:
105                 if (rc.getResultTribSlot() != null && rc.getResultTribPort() != null) {
106                     @SuppressWarnings("unchecked")
107                     List<Uint16> tribSlotList = (List<Uint16>) rc.getResultTribSlot().values().toArray()[0];
108                     atoZDirectionBldr.setAToZWavelengthNumber(Uint32.valueOf(0))
109                             .setTribPortNumber(Uint16.valueOf(rc.getResultTribPort().values().toArray()[0].toString()))
110                             .setTribSlotNumber(tribSlotList.get(0));
111                 } else {
112                     LOG.error("Trib port and trib slot number should be present");
113                     atoZDirectionBldr.setTribSlotNumber(Uint16.valueOf(0)).setTribPortNumber(Uint16.valueOf(0));
114                 }
115                 break;
116             default:
117                 LOG.warn("unknown service type : unable to set Min/Max frequencies");
118                 break;
119         }
120         return atoZDirectionBldr;
121     }
122
123     /**
124      * Create a builder for ZtoADirection object.
125      * @param ztoaMap Map of ZToA object
126      * @return a builder for ZtoADirection object
127      */
128     private ZToADirectionBuilder buildZtoADirection(Map<ZToAKey, ZToA> ztoaMap) {
129         ZToADirectionBuilder ztoADirectionBldr = new ZToADirectionBuilder().setRate(Uint32.valueOf(rc.getRate()))
130                 .setModulationFormat(GridConstant.RATE_MODULATION_FORMAT_MAP
131                         .getOrDefault(Uint32.valueOf(rc.getRate()), ModulationFormat.DpQpsk).getName())
132                 .setZToA(ztoaMap);
133         switch (rc.getServiceType()) {
134             case StringConstants.SERVICE_TYPE_400GE:
135             case StringConstants.SERVICE_TYPE_100GE:
136             case StringConstants.SERVICE_TYPE_OTU4:
137                 ztoADirectionBldr.setZToAMaxFrequency(new FrequencyTHz(rc.getMaxFreq()));
138                 ztoADirectionBldr.setZToAMinFrequency(new FrequencyTHz(rc.getMinFreq()));
139                 ztoADirectionBldr.setZToAWavelengthNumber(Uint32.valueOf(rc.getResultWavelength()));
140                 break;
141             case StringConstants.SERVICE_TYPE_10GE:
142             case StringConstants.SERVICE_TYPE_1GE:
143             case StringConstants.SERVICE_TYPE_ODU4:
144                 if (rc.getResultTribSlot() != null && rc.getResultTribPort() != null) {
145                     @SuppressWarnings("unchecked")
146                     List<Uint16> tribSlotList = (List<Uint16>) rc.getResultTribSlot().values().toArray()[0];
147                     ztoADirectionBldr.setZToAWavelengthNumber(Uint32.valueOf(0))
148                             .setTribPortNumber(Uint16.valueOf(rc.getResultTribPort().values().toArray()[0].toString()))
149                             .setTribSlotNumber(tribSlotList.get(0));
150                 } else {
151                     LOG.error("Trib port and trib slot number should be present");
152                     ztoADirectionBldr.setTribSlotNumber(Uint16.valueOf(0)).setTribPortNumber(Uint16.valueOf(0));
153                 }
154                 break;
155             default:
156                 LOG.warn("unknown service type : unable to set Min/Max frequencies");
157                 break;
158         }
159         return ztoADirectionBldr;
160     }
161
162     @SuppressWarnings("java:S138")
163     //sonar issue This method has 77 lines, which is greater than the 75 lines authorized. Split it into smaller
164     //ignore as it's not relevant to split it from functional point
165     private void buildAtoZ(Map<AToZKey, AToZ> atozMap, List<PceLink> path) {
166         Integer index = 0;
167         PceLink lastLink = null;
168         AToZ lastResource = null;
169
170         // build A side Client TP
171         String tpName = path.get(0).getClient();
172         String xname = path.get(0).getSourceId().getValue();
173         TerminationPoint stp = new TerminationPointBuilder()
174                 .setTpId(tpName).setTpNodeId(xname)
175                 .build();
176
177         AToZKey clientKey = new AToZKey(index.toString());
178         Resource clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
179         AToZ firstResource = new AToZBuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
180         atozMap.put(firstResource.key(),firstResource);
181         index += 1;
182         for (PceLink pcelink : path) {
183             String srcName = pcelink.getSourceId().getValue();
184             // Nodes
185             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce
186                 .resource.resource.resource.Node sourceNode = new NodeBuilder()
187                 .setNodeId(srcName)
188                 .build();
189
190             // Source Resource
191             AToZKey sourceKey = new AToZKey(index.toString());
192             Resource nodeResource1 = new ResourceBuilder().setResource(sourceNode).setState(State.InService).build();
193             AToZ srcResource = new AToZBuilder().setId(srcName).withKey(sourceKey).setResource(nodeResource1).build();
194             index += 1;
195             atozMap.put(srcResource.key(),srcResource);
196
197             // source TP
198             tpName = pcelink.getSourceTP().toString();
199             stp = new TerminationPointBuilder()
200                     .setTpNodeId(srcName).setTpId(tpName)
201                     .build();
202
203             // Resource
204             AToZKey srcTPKey = new AToZKey(index.toString());
205             Resource tpResource1 = new ResourceBuilder().setResource(stp).setState(State.InService).build();
206             AToZ stpResource = new AToZBuilder().setId(tpName).withKey(srcTPKey).setResource(tpResource1).build();
207             index += 1;
208             atozMap.put(stpResource.key(),stpResource);
209
210             String linkName = pcelink.getLinkId().getValue();
211             // Link
212             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce
213                 .resource.resource.resource.Link atozLink = new LinkBuilder()
214                 .setLinkId(linkName)
215                 .build();
216
217             // Link Resource
218             AToZKey linkKey = new AToZKey(index.toString());
219             Resource nodeResource2 = new ResourceBuilder().setResource(atozLink).setState(pcelink.getState()).build();
220             AToZ linkResource = new AToZBuilder().setId(linkName).withKey(linkKey).setResource(nodeResource2).build();
221             index += 1;
222             atozMap.put(linkResource.key(),linkResource);
223
224             String destName = pcelink.getDestId().getValue();
225             // target TP
226             tpName = pcelink.getDestTP().toString();
227             TerminationPoint dtp = new TerminationPointBuilder()
228                 .setTpNodeId(destName).setTpId(tpName)
229                 .build();
230
231             // Resource
232             AToZKey destTPKey = new AToZKey(index.toString());
233             Resource tpResource2 = new ResourceBuilder().setResource(dtp).setState(State.InService).build();
234             AToZ ttpResource = new AToZBuilder().setId(tpName).withKey(destTPKey).setResource(tpResource2).build();
235             index += 1;
236             atozMap.put(ttpResource.key(),ttpResource);
237
238             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce
239                 .resource.resource.resource.Node targetNode = new NodeBuilder()
240                 .setNodeId(destName)
241                 .build();
242
243             // Target Resource
244             AToZKey targetKey = new AToZKey(index.toString());
245             Resource nodeResource3 = new ResourceBuilder().setResource(targetNode).setState(State.InService).build();
246             lastResource = new AToZBuilder().setId(destName).withKey(targetKey).setResource(nodeResource3).build();
247
248             lastLink = pcelink;
249         }
250
251         if (lastResource != null) {
252             atozMap.put(lastResource.key(),lastResource);
253         }
254
255         // build Z side Client TP
256         tpName = lastLink.getClient();
257         xname = lastLink.getDestId().getValue();
258         stp = new TerminationPointBuilder()
259                 .setTpNodeId(xname).setTpId(tpName)
260                 .build();
261
262         index += 1;
263         clientKey = new AToZKey(index.toString());
264         clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
265         lastResource = new AToZBuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
266         atozMap.put(lastResource.key(),lastResource);
267
268     }
269
270     private void buildZtoA(Map<ZToAKey, ZToA> ztoaList, List<PceLink> path) {
271         Integer index = 0;
272         PceLink lastLink = null;
273         ZToA lastResource = null;
274
275         // build Z size Client TP
276         PceLink pcelink = this.allPceLinks.get(path.get(0).getOppositeLink());
277         String tpName = pcelink.getClient();
278         String xname = pcelink.getSourceId().getValue();
279         TerminationPoint stp = new TerminationPointBuilder()
280                 .setTpNodeId(xname).setTpId(tpName)
281                 .build();
282
283         ZToAKey clientKey = new ZToAKey(index.toString());
284         Resource clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
285         ZToA firstResource = new ZToABuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
286         ztoaList.put(firstResource.key(),firstResource);
287         index += 1;
288
289         for (PceLink pcelinkAtoZ : path) {
290
291             pcelink = this.allPceLinks.get(pcelinkAtoZ.getOppositeLink());
292             LOG.debug("link to oppsite: {} to {}", pcelinkAtoZ, pcelink);
293
294             String srcName = pcelink.getSourceId().getValue();
295
296
297             // Nodes
298             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce
299                 .resource.resource.resource.Node sourceNode = new NodeBuilder()
300                 .setNodeId(srcName).build();
301
302
303             // Source Resource
304             ZToAKey sourceKey = new ZToAKey(index.toString());
305             Resource nodeResource1 = new ResourceBuilder().setResource(sourceNode).setState(State.InService).build();
306             ZToA srcResource = new ZToABuilder().setId(srcName).withKey(sourceKey).setResource(nodeResource1).build();
307             index += 1;
308             ztoaList.put(srcResource.key(),srcResource);
309
310             // source TP
311             tpName = pcelink.getSourceTP().toString();
312             stp = new TerminationPointBuilder()
313                     .setTpNodeId(srcName).setTpId(tpName)
314                     .build();
315
316             // Resource
317             ZToAKey srcTPKey = new ZToAKey(index.toString());
318             Resource tpResource1 = new ResourceBuilder().setResource(stp).setState(State.InService).build();
319             ZToA stpResource = new ZToABuilder().setId(tpName).withKey(srcTPKey).setResource(tpResource1).build();
320             index += 1;
321             ztoaList.put(stpResource.key(),stpResource);
322
323             String linkName = pcelink.getLinkId().getValue();
324             // Link
325             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce
326                 .resource.resource.resource.Link ztoaLink = new LinkBuilder()
327                 .setLinkId(linkName).build();
328
329             // Link Resource
330             ZToAKey linkKey = new ZToAKey(index.toString());
331             Resource nodeResource2 = new ResourceBuilder().setResource(ztoaLink).setState(State.InService).build();
332             ZToA linkResource = new ZToABuilder().setId(linkName).withKey(linkKey).setResource(nodeResource2).build();
333             index += 1;
334             ztoaList.put(linkResource.key(),linkResource);
335
336             String destName = pcelink.getDestId().getValue();
337             // target TP
338             tpName = pcelink.getDestTP().toString();
339             TerminationPoint ttp = new TerminationPointBuilder()
340                     .setTpNodeId(destName).setTpId(tpName).build();
341
342             // Resource
343             ZToAKey destTPKey = new ZToAKey(index.toString());
344             Resource tpResource2 = new ResourceBuilder().setResource(ttp).setState(State.InService).build();
345             ZToA ttpResource = new ZToABuilder().setId(tpName).withKey(destTPKey).setResource(tpResource2).build();
346             index += 1;
347             ztoaList.put(ttpResource.key(),ttpResource);
348
349
350             org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce
351                 .resource.resource.resource.Node targetNode = new NodeBuilder()
352                 .setNodeId(destName).build();
353             // Target Resource
354             ZToAKey targetKey = new ZToAKey(index.toString());
355             Resource nodeResource3 = new ResourceBuilder().setResource(targetNode).setState(State.InService).build();
356             lastResource = new ZToABuilder().setId(destName).withKey(targetKey).setResource(nodeResource3).build();
357
358             lastLink = pcelink;
359         }
360         if (lastResource != null) {
361             ztoaList.put(lastResource.key(),lastResource);
362         }
363
364         // build Z side Client TP
365         tpName = lastLink.getClient();
366         xname = lastLink.getDestId().getValue();
367         stp = new TerminationPointBuilder()
368                 .setTpNodeId(xname).setTpId(tpName).build();
369
370         index += 1;
371         clientKey = new ZToAKey(index.toString());
372         clientResource = new ResourceBuilder().setResource(stp).setState(State.InService).build();
373         lastResource = new ZToABuilder().setId(tpName).withKey(clientKey).setResource(clientResource).build();
374         ztoaList.put(lastResource.key(),lastResource);
375     }
376
377     public PceResult getReturnStructure() {
378         return rc;
379     }
380 }