Remove transportpce-routing-constraint model
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / constraints / PceConstraintsCalc.java
1 /*
2  * Copyright © 2016 AT&T 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.constraints;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.Optional;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.TimeUnit;
15 import java.util.concurrent.TimeoutException;
16 import java.util.stream.Collectors;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.transportpce.common.Timeouts;
19 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
20 import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestInput;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev181130.NodeIdType;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.constraints.CoRoutingOrGeneral;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.constraints.co.routing.or.general.CoRouting;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.constraints.co.routing.or.general.General;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.constraints.co.routing.or.general.general.Diversity;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.constraints.co.routing.or.general.general.Exclude;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.constraints.co.routing.or.general.general.Include;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.constraints.co.routing.or.general.general.Latency;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.diversity.existing.service.constraints.ExistingServiceApplicability;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.routing.constraints.HardConstraints;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.routing.constraints.SoftConstraints;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.PathDescription;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.Link;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.Node;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.PceMetric;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.opendaylight.yangtools.yang.common.Uint32;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 public class PceConstraintsCalc {
47     /* Logging. */
48     private static final Logger LOG = LoggerFactory.getLogger(PceConstraintsCalc.class);
49
50     private PceConstraints pceHardConstraints = new PceConstraints();
51     private PceConstraints pceSoftConstraints = new PceConstraints();
52     private PceMetric pceMetrics = PceMetric.HopCount;
53     private NetworkTransactionService networkTransactionService;
54
55     public PceConstraintsCalc(PathComputationRequestInput input, NetworkTransactionService networkTransactionService) {
56         LOG.debug("In PceconstraintsCalc start");
57
58         pceMetrics = input.getPceRoutingMetric();
59
60         this.networkTransactionService = networkTransactionService;
61
62         // TODO. for now metrics are set into hard structure
63         LOG.info("In PceConstraintsCalc: read PceMetric {}", pceMetrics);
64         pceHardConstraints.setPceMetrics(pceMetrics);
65
66         calcHardconstraints(input);
67         calcSoftconstraints(input);
68     }
69
70     private void calcHardconstraints(PathComputationRequestInput input) {
71         HardConstraints servicePathHardConstraints = input.getHardConstraints();
72         if (servicePathHardConstraints == null) {
73             LOG.info("In calcHardconstraints: no hard constraints.");
74             return;
75         }
76
77         CoRoutingOrGeneral coRoutingOrGeneral = servicePathHardConstraints.getCoRoutingOrGeneral();
78         readconstraints(coRoutingOrGeneral, pceHardConstraints);
79
80     }
81
82     private void calcSoftconstraints(PathComputationRequestInput input) {
83         SoftConstraints servicePathSoftConstraints = input.getSoftConstraints();
84         if (servicePathSoftConstraints == null) {
85             LOG.info("In calcSoftconstraints: no soft constraints.");
86             return;
87         }
88
89         CoRoutingOrGeneral coRoutingOrGeneral = servicePathSoftConstraints.getCoRoutingOrGeneral();
90         readconstraints(coRoutingOrGeneral, pceSoftConstraints);
91
92     }
93
94     private void readconstraints(CoRoutingOrGeneral coRoutingOrGeneral, PceConstraints constraints) {
95         LOG.debug("In readconstraints start");
96
97         if (coRoutingOrGeneral == null) {
98             LOG.info("In readHardconstraints: no CoRoutingOrGeneral constraints.");
99             return;
100         }
101
102         General tmpGeneral = null;
103         CoRouting tmpCoRouting = null;
104
105         if (coRoutingOrGeneral instanceof General) {
106             LOG.info("In readconstraints General {}", coRoutingOrGeneral);
107             tmpGeneral = (General) coRoutingOrGeneral;
108             readGeneralContrains(tmpGeneral, constraints);
109             return;
110         }
111
112         if (coRoutingOrGeneral instanceof CoRouting) {
113             LOG.info("In readconstraints CoRouting {}", coRoutingOrGeneral);
114             tmpCoRouting = (CoRouting) coRoutingOrGeneral;
115             readCoRoutingContrains(tmpCoRouting, constraints);
116         }
117     }
118
119     private void readGeneralContrains(General tmpGeneral, PceConstraints constraints) {
120         LOG.debug("In readGeneralContrains start");
121
122         if (tmpGeneral == null) {
123             LOG.info("In readGeneralContrains: no General constraints.");
124             return;
125         }
126
127         Latency latency = tmpGeneral.getLatency();
128         if (latency != null) {
129             constraints.setMaxLatency(latency.getMaxLatency().toJava());
130             LOG.info("In readGeneralContrains: read latency {}", latency);
131         }
132
133         Exclude exclude = tmpGeneral.getExclude();
134         if (exclude != null) {
135             readExclude(exclude, constraints);
136         }
137
138         Include include = tmpGeneral.getInclude();
139         if (include != null) {
140             readInclude(include, constraints);
141         }
142
143         Diversity diversity = tmpGeneral.getDiversity();
144         PceConstraints.ResourceType rt = PceConstraints.ResourceType.NONE;
145         if (diversity != null) {
146             ExistingServiceApplicability temp = diversity.getExistingServiceApplicability();
147             if (temp == null) {
148                 return;
149             }
150             if (Boolean.TRUE.equals(temp.getNode())) {
151                 rt = PceConstraints.ResourceType.NODE;
152             }
153             if (Boolean.TRUE.equals(temp.getSrlg())) {
154                 rt = PceConstraints.ResourceType.SRLG;
155             }
156             if (Boolean.TRUE.equals(temp.getSite())) {
157                 rt = PceConstraints.ResourceType.CLLI;
158             }
159             LOG.info("in readGeneralContrains {} list is :{}", rt, diversity);
160             readDiversity(diversity.getExistingService(), constraints, rt);
161         }
162     }
163
164     private void readExclude(Exclude exclude, PceConstraints constraints) {
165         List<NodeIdType> nodes = exclude.getNodeId();
166         if (nodes != null) {
167             List<String> elementsToExclude = new ArrayList<>();
168             for (NodeIdType node : nodes) {
169                 elementsToExclude.add(node.getValue());
170             }
171             constraints.setExcludeSupNodes(elementsToExclude);
172         }
173         List<Uint32> srlgs = exclude.getSrlgId();
174         if (srlgs != null) {
175             List<Long> elementsToExclude = new ArrayList<>();
176             for (Uint32 srlg : srlgs) {
177                 elementsToExclude.add(srlg.longValue());
178             }
179             constraints.setExcludeSRLG(elementsToExclude);
180         }
181         List<String> sites = exclude.getSite();
182         if (sites != null) {
183             constraints.setExcludeCLLI(exclude.getSite());
184         }
185     }
186
187     private void readInclude(Include include, PceConstraints constraints) {
188         List<NodeIdType> nodes = include.getNodeId();
189         if (nodes != null) {
190             for (NodeIdType node : nodes) {
191                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.NODE, node.getValue()));
192             }
193         }
194         List<Uint32> srlgs = include.getSrlgId();
195         if (srlgs != null) {
196             for (Uint32 srlg : srlgs) {
197                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.SRLG, srlg.toString()));
198             }
199         }
200         List<String> sites = include.getSite();
201         if (sites != null) {
202             for (String site : sites) {
203                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.CLLI, site));
204             }
205         }
206     }
207
208     private void readDiversity(List<String> srvList, PceConstraints constraints, PceConstraints.ResourceType rt) {
209
210         List<String> elementsToExclude = new ArrayList<>();
211         LOG.info("in readDiversity {}", srvList);
212
213         for (String srv : srvList) {
214             Optional<PathDescription> service = getPathDescriptionFromDatastore(srv);
215             if (service.isPresent()) {
216                 LOG.info("in readDiversity service list {}", service);
217                 switch (rt) {
218                     case NODE:
219                         elementsToExclude.addAll(getAToZNodeList(service.get()));
220                         LOG.info("readDiversity NODE : {}", elementsToExclude);
221                         if (elementsToExclude != null) {
222                             constraints.setExcludeNodes(elementsToExclude);
223                         }
224                         break;
225                     case SRLG:
226                         elementsToExclude.addAll(getSRLGList(service.get()));
227                         LOG.info("readDiversity SRLG : {}", elementsToExclude);
228                         if (elementsToExclude != null) {
229                             constraints.setExcludeSrlgLinks(elementsToExclude);
230                         }
231                         break;
232                     case CLLI:
233                         /// Retrieve nodes into dedicated CLLI list
234                         /// during node validation check their CLLI and build CLLI exclude list
235                         elementsToExclude.addAll(getAToZNodeList(service.get()));
236                         LOG.info("readDiversity CLLI : {}", elementsToExclude);
237                         if (elementsToExclude != null) {
238                             constraints.setExcludeClliNodes(elementsToExclude);
239                         }
240                         break;
241                     default:
242                         LOG.info("in readDiversity unsupported divercity type {}", rt);
243                 }
244
245             } else {
246                 LOG.info("in readDiversity srv={} is not present", srv);
247             }
248         }
249     }
250
251     private List<String> getAToZNodeList(PathDescription pathDescription) {
252         List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
253         return aendToZList.stream().filter(aToZ -> {
254             if (aToZ.getResource() == null || aToZ.getResource().getResource() == null) {
255                 LOG.warn("Diversity constraint: Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
256                 return false;
257             }
258             return aToZ.getResource().getResource() instanceof Node;
259         }).filter(aToZ -> {
260             Node node = (Node) aToZ.getResource().getResource();
261             if (node.getNodeId() == null) {
262                 LOG.warn("Node in AToZ node {} contains null! Skipping this node!", aToZ.getId());
263                 return false;
264             }
265             return true;
266         }).map(aToZ -> {
267             Node node = ((Node) aToZ.getResource().getResource());
268             return node.getNodeId();
269         }).collect(Collectors.toList());
270     }
271
272     private List<String> getSRLGList(PathDescription pathDescription) {
273         List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
274         return aendToZList.stream().filter(aToZ -> {
275             if (aToZ.getResource() == null
276                     || aToZ.getResource().getResource() == null) {
277                 LOG.warn("Diversity constraint: Resource of AToZ {} is null! Skipping this resource!", aToZ.getId());
278                 return false;
279             }
280             return aToZ.getResource().getResource() instanceof Link;
281         }).filter(aToZ -> {
282             Link link = (Link) aToZ.getResource().getResource();
283             if (link.getLinkId() == null) {
284                 LOG.warn("Link in AToZ link {} contains null! Skipping this link!", aToZ.getId());
285                 return false;
286             }
287             return true;
288         }).map(aToZ -> {
289             return ((Link) aToZ.getResource().getResource()).getLinkId();
290         }).collect(Collectors.toList());
291     }
292
293     private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
294         Optional<PathDescription> result = Optional.empty();
295         InstanceIdentifier<ServicePaths> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
296                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
297         try {
298             LOG.info("PCE diversity constraints: Getting path description for service {}", serviceName);
299             ServicePaths servicePaths =
300                 networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
301                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).get();
302             if (servicePaths != null) {
303                 PathDescription path = servicePaths.getPathDescription();
304                 if (path != null) {
305                     result = Optional.of(path);
306                 }
307             }
308         } catch (InterruptedException | ExecutionException | TimeoutException e) {
309             LOG.warn(
310                 "PCE diversity constraints: Exception while getting path description from datastore {} for service {}!",
311                 pathDescriptionIID,serviceName, e);
312             return result;
313         }
314         return result;
315     }
316
317     private void readCoRoutingContrains(CoRouting tmpcoRouting, PceConstraints constraints) {
318         LOG.info("In readCoRoutingContrains start");
319
320         if (tmpcoRouting == null) {
321             LOG.info("In readCoRoutingContrains: no General constraints.");
322         }
323
324     }
325
326     public PceConstraints getPceHardConstraints() {
327         return pceHardConstraints;
328     }
329
330     public PceConstraints getPceSoftConstraints() {
331         return pceSoftConstraints;
332     }
333
334     public PceMetric getPceMetrics() {
335         return pceMetrics;
336     }
337
338 }