Supporting new paths computed by GNPy
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / gnpy / GnpyServiceImpl.java
1 /*
2  * Copyright © 2019 Orange, 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.gnpy;
10
11 import java.math.BigDecimal;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17
18 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
19 import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
20 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Elements;
21 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.RouteIncludeEro;
22 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.TeHopType;
23 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.TeNodeId;
24 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.TePathDisjointness;
25 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.TeTpId;
26 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.common.constraints_config.TeBandwidth;
27 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.common.constraints_config.TeBandwidthBuilder;
28 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.explicit.route.hop.Type;
29 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.explicit.route.hop.type.NumUnnumHopBuilder;
30 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.explicit.route.hop.type.num.unnum.hop.NumUnnumHop;
31 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.generic.path.constraints.PathConstraints;
32 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.generic.path.constraints.PathConstraintsBuilder;
33 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.gnpy.specific.parameters.EffectiveFreqSlot;
34 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.gnpy.specific.parameters.EffectiveFreqSlotBuilder;
35 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.path.route.objects.ExplicitRouteObjects;
36 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.path.route.objects.ExplicitRouteObjectsBuilder;
37 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.path.route.objects.explicit.route.objects.RouteObjectIncludeExclude;
38 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeBuilder;
39 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.service.PathRequest;
40 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.service.PathRequestBuilder;
41 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.synchronization.info.Synchronization;
42 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.synchronization.info.SynchronizationBuilder;
43 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.synchronization.info.synchronization.Svec;
44 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.synchronization.info.synchronization.SvecBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInput;
46 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirection;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ZToADirection;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.atoz.direction.AToZ;
49 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ztoa.direction.ZToA;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 /**
55  * Class to create the topology corresponding to GNPy requirements.
56  *
57  * @author Ahmed Triki ( ahmed.triki@orange.com )
58  *
59  */
60
61 public class GnpyServiceImpl {
62     private static final Logger LOG = LoggerFactory.getLogger(GnpyServiceImpl.class);
63     private List<PathRequest> pathRequest = new ArrayList<>();
64     private List<Synchronization> synchronization = new ArrayList<>();
65     private Map<String, String> mapDisgNodeRefNode = new HashMap<String, String>();
66     private Map<String, IpAddress> mapNodeRefIp = new HashMap<String, IpAddress>();
67     private Map<String, String> mapLinkFiber = new HashMap<String, String>();
68     private Map<String, IpAddress> mapFiberIp = new HashMap<String, IpAddress>();
69     private List<Elements> elements = new ArrayList<>();
70
71     /*
72      * Construct the GnpyServiceImpl
73      */
74     public GnpyServiceImpl(PathComputationRequestInput input, AToZDirection atoz, Long requestId, GnpyTopoImpl gnpyTopo,
75         PceConstraints pceHardConstraints) {
76         this.elements = gnpyTopo.getElements();
77         this.mapDisgNodeRefNode = gnpyTopo.getMapDisgNodeRefNode();
78         this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
79         this.mapLinkFiber = gnpyTopo.getMapLinkFiber();
80         this.mapFiberIp = gnpyTopo.getMapFiberIp();
81
82         this.pathRequest = extractPathRequest(input, atoz, requestId, pceHardConstraints);
83         this.synchronization = extractSynchronization(requestId);
84     }
85
86     public GnpyServiceImpl(PathComputationRequestInput input, ZToADirection ztoa, Long requestId, GnpyTopoImpl gnpyTopo,
87         PceConstraints pceHardConstraints) {
88         this.elements = gnpyTopo.getElements();
89         this.mapDisgNodeRefNode = gnpyTopo.getMapDisgNodeRefNode();
90         this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
91         this.mapLinkFiber = gnpyTopo.getMapLinkFiber();
92         this.mapFiberIp = gnpyTopo.getMapFiberIp();
93
94         pathRequest = extractPathRequest(input, ztoa, requestId, pceHardConstraints);
95         synchronization = extractSynchronization(requestId);
96     }
97
98     //Create the pathRequest
99     public List<PathRequest> extractPathRequest(PathComputationRequestInput input, AToZDirection atoz, Long requestId,
100         PceConstraints pceHardConstraints) {
101         // 1.1 Create explicitRouteObjects
102         // 1.1.1. create RouteObjectIncludeExclude list
103         List<RouteObjectIncludeExclude> routeObjectIncludeExcludes = new ArrayList<>();
104         IpAddress ipAddressCurrent = null;
105         Long index = (long) 0;
106         // List of A to Z
107         List<AToZ> listAtoZ = atoz.getAToZ();
108         if (listAtoZ != null) {
109             int atozSize = listAtoZ.size();
110             for (int i = 0; i < atozSize; i++) {
111                 String nodeId = null;
112                 if (listAtoZ.get(i).getResource().getResource()
113                     instanceof
114                         org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
115                             .pce.resource.resource.resource.Node) {
116                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
117                         .pce.resource.resource.resource.Node node =
118                         (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
119                             .pce.resource.resource.resource.Node) listAtoZ.get(i).getResource().getResource();
120
121                     nodeId = node.getNodeId();
122                     if (nodeId != null) {
123                         String nodeRef = this.mapDisgNodeRefNode.get(nodeId);
124                         IpAddress ipAddress = this.mapNodeRefIp.get(nodeRef);
125                         for (Elements element : this.elements) {
126                             if (element.getUid().contains(ipAddress.getIpv4Address().getValue().toString())) {
127                                 if ((ipAddressCurrent == null) || (ipAddressCurrent != ipAddress)) {
128                                     ipAddressCurrent = ipAddress;
129                                     // Fill in routeObjectIncludeExcludes
130                                     RouteObjectIncludeExclude routeObjectIncludeExclude1 = addRouteObjectIncludeExclude(
131                                         ipAddress, 1, index);
132                                     routeObjectIncludeExcludes.add(routeObjectIncludeExclude1);
133                                     index++;
134                                 }
135                                 break;
136                             }
137                         }
138                     } else {
139                         LOG.warn("node ID is null");
140                     }
141                     // TODO else if termination point not implemented in this
142                     // version
143                 } else if (listAtoZ.get(i).getResource().getResource()
144                     instanceof
145                         org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
146                             .pce.resource.resource.resource.Link) {
147                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
148                         .pce.resource.resource.resource.Link link =
149                         (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
150                             .pce.resource.resource.resource.Link) listAtoZ.get(i).getResource().getResource();
151
152                     String clfi = this.mapLinkFiber.get(link.getLinkId());
153                     IpAddress fiberIp = this.mapFiberIp.get(clfi);
154                     if (clfi != null) {
155                         RouteObjectIncludeExclude routeObjectIncludeExclude1 = addRouteObjectIncludeExclude(fiberIp, 1,
156                             index);
157                         routeObjectIncludeExcludes.add(routeObjectIncludeExclude1);
158                         index++;
159                     }
160                 }
161             }
162         }
163         else {
164             routeObjectIncludeExcludes = extractHardConstraints(pceHardConstraints);
165             //TODO integrate the maxLatency/ Metric and max OSNR as additional constraints to GNPy
166         }
167
168         // 1.1. Create ExplicitRouteObjects
169         ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
170             .setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
171         // 1.2 Create a path constraints
172         Long rate = atoz.getRate();
173         // 1.2.1. Create EffectiveFreqSlot
174         List<EffectiveFreqSlot> effectiveFreqSlot = new ArrayList<>();
175         EffectiveFreqSlot effectiveFreqSlot1 = new EffectiveFreqSlotBuilder().setM(5).setN(8).build();
176         effectiveFreqSlot.add(effectiveFreqSlot1);
177         // 1.2.2. Create Te-Bandwidth
178         TeBandwidth teBandwidth = new TeBandwidthBuilder().setPathBandwidth(new BigDecimal(rate))
179             .setTechnology("flexi-grid").setTrxType("openroadm-beta1").setTrxMode("W100G")
180             .setEffectiveFreqSlot(effectiveFreqSlot).setSpacing(new BigDecimal(50000000000.0)).build();
181         PathConstraints pathConstraints = new PathConstraintsBuilder().setTeBandwidth(teBandwidth).build();
182         // 1.3. Create the source and destination nodes
183         String sourceNode = input.getServiceAEnd().getNodeId();
184         String destNode = input.getServiceZEnd().getNodeId();
185         // Create the path-request elements
186         // Create the path request
187         List<PathRequest> pathRequestList = new ArrayList<>();
188         PathRequest pathRequest1 = new PathRequestBuilder().setRequestId(requestId)
189             .setSource(this.mapNodeRefIp.get(sourceNode)).setDestination(this.mapNodeRefIp.get(destNode))
190             .setSrcTpId("srcTpId".getBytes()).setDstTpId("dstTpId".getBytes()).setPathConstraints(pathConstraints)
191             .setExplicitRouteObjects(explicitRouteObjects).build();
192         pathRequestList.add(pathRequest1);
193         return pathRequestList;
194     }
195
196     public List<PathRequest> extractPathRequest(PathComputationRequestInput input, ZToADirection ztoa, Long requestId,
197         PceConstraints pceHardConstraints) {
198         // 1.1 Create explicitRouteObjects
199         // 1.1.1. create RouteObjectIncludeExclude list
200         List<RouteObjectIncludeExclude> routeObjectIncludeExcludes = new ArrayList<>();
201         IpAddress ipAddressCurrent = null;
202         Long index = (long) 0;
203         List<ZToA> listZtoA = ztoa.getZToA();
204         if (listZtoA != null) {
205             int ztoaSize = listZtoA.size();
206             for (int i = 0; i < ztoaSize; i++) {
207                 String nodeId = null;
208                 if (listZtoA.get(i).getResource().getResource()
209                     instanceof
210                         org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
211                             .pce.resource.resource.resource.Node) {
212                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
213                         .pce.resource.resource.resource.Node node =
214                         (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
215                             .pce.resource.resource.resource.Node) listZtoA.get(i).getResource().getResource();
216                     nodeId = node.getNodeId();
217                     if (nodeId != null) {
218                         String nodeRef = this.mapDisgNodeRefNode.get(nodeId);
219                         IpAddress ipAddress = this.mapNodeRefIp.get(nodeRef);
220                         for (Elements element : this.elements) {
221                             if (element.getUid().contains(ipAddress.getIpv4Address().getValue().toString())) {
222                                 if ((ipAddressCurrent == null) || (ipAddressCurrent != ipAddress)) {
223                                     ipAddressCurrent = ipAddress;
224                                     // Fill in routeObjectIncludeExcludes
225                                     RouteObjectIncludeExclude routeObjectIncludeExclude1 = addRouteObjectIncludeExclude(
226                                         ipAddress, 1, index);
227                                     routeObjectIncludeExcludes.add(routeObjectIncludeExclude1);
228                                     index++;
229                                 }
230                                 break;
231                             }
232                         }
233                     } else {
234                         LOG.warn("node ID is null");
235                     }
236                     // TODO else if termination point not implemented in this
237                     // version
238                 } else if (listZtoA.get(i).getResource().getResource()
239                     instanceof
240                         org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
241                             .pce.resource.resource.resource.Link) {
242
243                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
244                         .pce.resource.resource.resource.Link link =
245                         (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017
246                             .pce.resource.resource.resource.Link) listZtoA.get(i).getResource().getResource();
247                     String clfi = this.mapLinkFiber.get(link.getLinkId());
248                     IpAddress fiberIp = this.mapFiberIp.get(clfi);
249                     if (clfi != null) {
250                         RouteObjectIncludeExclude routeObjectIncludeExclude1 =
251                             addRouteObjectIncludeExclude(fiberIp, 1, index);
252                         routeObjectIncludeExcludes.add(routeObjectIncludeExclude1);
253                         index++;
254                     }
255
256                 }
257             }
258         } else {
259             routeObjectIncludeExcludes = extractHardConstraints(pceHardConstraints);
260         }
261
262         // 1.1. Create ExplicitRouteObjects
263         ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
264             .setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
265         // 1.2 Create a path constraints
266         Long rate = ztoa.getRate();
267         // 1.2.1. Create EffectiveFreqSlot
268         List<EffectiveFreqSlot> effectiveFreqSlot = new ArrayList<>();
269         EffectiveFreqSlot effectiveFreqSlot1 = new EffectiveFreqSlotBuilder().setM(5).setN(8).build();
270         effectiveFreqSlot.add(effectiveFreqSlot1);
271         // 1.2.2. Create Te-Bandwidth
272         TeBandwidth teBandwidth = new TeBandwidthBuilder().setPathBandwidth(new BigDecimal(rate))
273             .setTechnology("flexi-grid").setTrxType("openroadm-beta1").setTrxMode("W100G")
274             .setEffectiveFreqSlot(effectiveFreqSlot).setSpacing(new BigDecimal(50000000000.0)).build();
275         PathConstraints pathConstraints = new PathConstraintsBuilder().setTeBandwidth(teBandwidth).build();
276         // 1.3. Create the source and destination nodes
277         String sourceNode = input.getServiceZEnd().getNodeId();
278         String destNode = input.getServiceAEnd().getNodeId();
279         // Create the path-request elements
280         // Create the path request
281         List<PathRequest> pathRequestList = new ArrayList<>();
282         PathRequest pathRequest1 = new PathRequestBuilder().setRequestId(requestId)
283             .setSource(this.mapNodeRefIp.get(sourceNode)).setDestination(this.mapNodeRefIp.get(destNode))
284             .setSrcTpId("srcTpId".getBytes()).setDstTpId("dstTpId".getBytes()).setPathConstraints(pathConstraints)
285             .setExplicitRouteObjects(explicitRouteObjects).build();
286         pathRequestList.add(pathRequest1);
287         return pathRequestList;
288     }
289
290   //Create RouteObjectIncludeExclude list
291     public List<RouteObjectIncludeExclude> extractHardConstraints(PceConstraints pceHardConstraints) {
292         List<String> listNodeToInclude = getListToInclude(pceHardConstraints);
293         List<RouteObjectIncludeExclude> routeObjectIncludeExcludes = new ArrayList<>();
294         IpAddress ipAddressCurrent = null;
295         Long index = (long) 0;
296         if (listNodeToInclude != null) {
297             for (int i = 0; i < listNodeToInclude.size(); i++) {
298                 String nodeId = listNodeToInclude.get(i);
299                 if (nodeId != null) {
300                     IpAddress ipAddress = this.mapNodeRefIp.get(nodeId);
301                     for (Elements element : this.elements) {
302                         if (element.getUid().contains(ipAddress.getIpv4Address().getValue().toString())) {
303                             if ((ipAddressCurrent == null) || (ipAddressCurrent != ipAddress)) {
304                                 ipAddressCurrent = ipAddress;
305                                 // Fill in routeObjectIncludeExcludes
306                                 RouteObjectIncludeExclude routeObjectIncludeExclude1 = addRouteObjectIncludeExclude(
307                                     ipAddress, 1, index);
308                                 routeObjectIncludeExcludes.add(routeObjectIncludeExclude1);
309                                 index++;
310                             }
311                             break;
312                         }
313                     }
314                 } else {
315                     LOG.warn("node ID is null");
316                 }
317             }
318         }
319         return routeObjectIncludeExcludes;
320     }
321
322     // Create the synchronization
323     public List<Synchronization> extractSynchronization(Long requestId) {
324         // Create RequestIdNumber
325         List<Long> requestIdNumber = new ArrayList<>();
326         requestIdNumber.add(requestId);
327         // Create a synchronization
328         Svec svec = new SvecBuilder().setRelaxable(true).setDisjointness(new TePathDisjointness(true, true, false))
329             .setRequestIdNumber(requestIdNumber).build();
330         List<Synchronization> synchro = new ArrayList<>();
331         Synchronization synchronization1 = new SynchronizationBuilder().setSynchronizationId(new Long(0)).setSvec(svec)
332             .build();
333         synchro.add(synchronization1);
334         return (synchro);
335     }
336
337     // Add routeObjectIncludeExclude
338     private RouteObjectIncludeExclude addRouteObjectIncludeExclude(IpAddress ipAddress, long teTpValue, long index) {
339         TeNodeId teNodeId = new TeNodeId(ipAddress);
340         TeTpId teTpId = new TeTpId(teTpValue);
341         NumUnnumHop numUnnumHop = new org.opendaylight.yang.gen.v1.gnpy.path.rev190502.explicit.route.hop.type.num
342             .unnum.hop.NumUnnumHopBuilder().setNodeId(teNodeId.getIpv4Address().getValue().toString())
343             .setLinkTpId(teTpId.getUint32().toString()).setHopType(TeHopType.STRICT).build();
344         Type type1 = new NumUnnumHopBuilder().setNumUnnumHop(numUnnumHop).build();
345         // Create routeObjectIncludeExclude element 1
346         RouteObjectIncludeExclude routeObjectIncludeExclude1 = new RouteObjectIncludeExcludeBuilder().setIndex(index)
347             .setExplicitRouteUsage(RouteIncludeEro.class).setType(type1).build();
348         return routeObjectIncludeExclude1;
349     }
350
351     // Create the list of nodes to include
352     private List<String> getListToInclude(PceConstraints pceHardConstraints) {
353         List<String> listNodeToInclude = new ArrayList<>();
354         if (pceHardConstraints != null) {
355             List<ResourcePair> listToInclude = pceHardConstraints.getListToInclude();
356             Iterator<ResourcePair> it = listToInclude.iterator();
357             while (it.hasNext()) {
358                 ResourcePair rs = it.next();
359                 if (rs.getType().name().equals("NODE")) {
360                     listNodeToInclude.add(rs.getName());
361                 }
362             }
363         }
364         return listNodeToInclude;
365     }
366
367     public List<PathRequest> getPathRequest() {
368         return pathRequest;
369     }
370
371     public void setPathRequest(List<PathRequest> pathRequest) {
372         this.pathRequest = pathRequest;
373     }
374
375     public List<Synchronization> getSynchronization() {
376         return synchronization;
377     }
378
379     public void setSynchronization(List<Synchronization> synchronization) {
380         this.synchronization = synchronization;
381     }
382
383 }