2 * Copyright © 2016 AT&T and others. All rights reserved.
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
8 package org.opendaylight.transportpce.pce.constraints;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.Comparator;
13 import java.util.List;
14 import java.util.Optional;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.TimeUnit;
17 import java.util.concurrent.TimeoutException;
18 import java.util.stream.Collectors;
19 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
20 import org.opendaylight.transportpce.common.Timeouts;
21 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput;
23 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.PathDescription;
24 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.atoz.direction.AToZ;
25 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.pce.resource.resource.resource.Link;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.pce.resource.resource.resource.Node;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp.PceMetric;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.CoRoutingOrGeneral;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.CoRouting;
30 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.General;
31 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Diversity;
32 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Exclude;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Include;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Latency;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.include_.OrderedHops;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.diversity.existing.service.contraints.sp.ExistingServiceApplicability;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.ordered.constraints.sp.hop.type.HopType;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.SoftConstraints;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 public class PceConstraintsCalc {
49 private static final Logger LOG = LoggerFactory.getLogger(PceConstraintsCalc.class);
50 private static final Comparator<OrderedHops> ORDERED_HOP_COMPARATOR =
51 Comparator.comparing(OrderedHops::getHopNumber);
53 private PceConstraints pceHardConstraints = new PceConstraints();
54 private PceConstraints pceSoftConstraints = new PceConstraints();
55 private PceMetric pceMetrics = PceMetric.HopCount;
56 private NetworkTransactionService networkTransactionService;
58 public PceConstraintsCalc(PathComputationRequestInput input, NetworkTransactionService networkTransactionService) {
59 LOG.debug("In PceconstraintsCalc start");
61 pceMetrics = input.getPceMetric();
63 this.networkTransactionService = networkTransactionService;
65 // TODO. for now metrics are set into hard structure
66 LOG.info("In PceConstraintsCalc: read PceMetric {}", pceMetrics);
67 pceHardConstraints.setPceMetrics(pceMetrics);
69 calcHardconstraints(input);
70 calcSoftconstraints(input);
73 private void calcHardconstraints(PathComputationRequestInput input) {
74 HardConstraints servicePathHardConstraints = input.getHardConstraints();
75 if (servicePathHardConstraints == null) {
76 LOG.info("In calcHardconstraints: no hard constraints.");
80 CoRoutingOrGeneral coRoutingOrGeneral = servicePathHardConstraints.getCoRoutingOrGeneral();
81 readconstraints(coRoutingOrGeneral, pceHardConstraints);
85 private void calcSoftconstraints(PathComputationRequestInput input) {
86 SoftConstraints servicePathSoftConstraints = input.getSoftConstraints();
87 if (servicePathSoftConstraints == null) {
88 LOG.info("In calcSoftconstraints: no soft constraints.");
92 CoRoutingOrGeneral coRoutingOrGeneral = servicePathSoftConstraints.getCoRoutingOrGeneral();
93 readconstraints(coRoutingOrGeneral, pceSoftConstraints);
97 private void readconstraints(CoRoutingOrGeneral coRoutingOrGeneral, PceConstraints constraints) {
98 LOG.debug("In readconstraints start");
100 if (coRoutingOrGeneral == null) {
101 LOG.info("In readHardconstraints: no CoRoutingOrGeneral constraints.");
105 General tmpGeneral = null;
106 CoRouting tmpCoRouting = null;
108 if (coRoutingOrGeneral instanceof General) {
109 LOG.info("In readconstraints General {}", coRoutingOrGeneral);
110 tmpGeneral = (General) coRoutingOrGeneral;
111 readGeneralContrains(tmpGeneral, constraints);
115 if (coRoutingOrGeneral instanceof CoRouting) {
116 LOG.info("In readconstraints CoRouting {}", coRoutingOrGeneral);
117 tmpCoRouting = (CoRouting) coRoutingOrGeneral;
118 readCoRoutingContrains(tmpCoRouting, constraints);
122 private void readGeneralContrains(General tmpGeneral, PceConstraints constraints) {
123 LOG.debug("In readGeneralContrains start");
125 if (tmpGeneral == null) {
126 LOG.info("In readGeneralContrains: no General constraints.");
130 Latency latency = tmpGeneral.getLatency();
131 if (latency != null) {
132 constraints.setMaxLatency(latency.getMaxLatency().toJava());
133 LOG.info("In readGeneralContrains: read latency {}", latency);
136 Exclude exclude = tmpGeneral.getExclude();
137 List<String> elementsToExclude = null;
138 if (exclude != null) {
139 elementsToExclude = exclude.getNodeId();
140 if (elementsToExclude != null) {
141 constraints.setExcludeSupNodes(elementsToExclude);
144 elementsToExclude = exclude.getSRLG();
145 if (elementsToExclude != null) {
146 List<Long> srlgToExclude = new ArrayList<>();
147 for (String str : elementsToExclude) {
148 srlgToExclude.add(Long.parseLong(str));
150 constraints.setExcludeSRLG(srlgToExclude);
153 elementsToExclude = exclude.getClli();
154 if (elementsToExclude != null) {
155 constraints.setExcludeCLLI(elementsToExclude);
159 Include include = tmpGeneral.getInclude();
160 if (include != null) {
161 List<OrderedHops> listHops = new ArrayList<>(include.nonnullOrderedHops().values());
162 if (listHops != null) {
163 readIncludeNodes(listHops, constraints);
165 LOG.debug("in readGeneralContrains INCLUDE {} ", include);
168 Diversity diversity = tmpGeneral.getDiversity();
169 PceConstraints.ResourceType rt = PceConstraints.ResourceType.NONE;
170 if (diversity != null) {
171 ExistingServiceApplicability temp = diversity.getExistingServiceApplicability();
175 if (Boolean.TRUE.equals(temp.isNode())) {
176 rt = PceConstraints.ResourceType.NODE;
178 if (Boolean.TRUE.equals(temp.isSrlg())) {
179 rt = PceConstraints.ResourceType.SRLG;
181 if (Boolean.TRUE.equals(temp.isClli())) {
182 rt = PceConstraints.ResourceType.CLLI;
184 LOG.info("in readGeneralContrains {} list is :{}", rt, diversity);
185 readDiversity(diversity.getExistingService(), constraints, rt);
190 private void readIncludeNodes(List<OrderedHops> listHops, PceConstraints constraints) {
191 Collections.sort(listHops, ORDERED_HOP_COMPARATOR);
192 for (int i = 0; i < listHops.size(); i++) {
193 HopType hoptype = listHops.get(i).getHopType().getHopType();
195 String hopt = hoptype.implementedInterface().getSimpleName();
196 LOG.info("in readIncludeNodes next hop to include {}", hopt);
199 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints
200 .rev171017.ordered.constraints.sp.hop.type.hop.type.Node
201 node = (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
202 .constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.Node) hoptype;
203 constraints.setListToInclude(new PceConstraints.ResourcePair(PceConstraints.ResourceType.NODE,
207 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints
208 .rev171017.ordered.constraints.sp.hop.type.hop.type.SRLG
209 srlg = (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
210 .constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.SRLG) hoptype;
211 constraints.setListToInclude(new PceConstraints.ResourcePair(PceConstraints.ResourceType.SRLG,
215 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints
216 .rev171017.ordered.constraints.sp.hop.type.hop.type.Clli
217 clli = (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
218 .constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.Clli) hoptype;
219 constraints.setListToInclude(new PceConstraints.ResourcePair(PceConstraints.ResourceType.CLLI,
223 LOG.error("in readIncludeNodes unsupported include type {}", hopt);
228 private void readDiversity(List<String> srvList, PceConstraints constraints, PceConstraints.ResourceType rt) {
230 List<String> elementsToExclude = new ArrayList<>();
231 LOG.info("in readDiversity {}", srvList);
233 for (String srv : srvList) {
234 Optional<PathDescription> service = getPathDescriptionFromDatastore(srv);
235 if (service.isPresent()) {
236 LOG.info("in readDiversity service list {}", service);
239 elementsToExclude.addAll(getAToZNodeList(service.get()));
240 LOG.info("readDiversity NODE : {}", elementsToExclude);
241 if (elementsToExclude != null) {
242 constraints.setExcludeNodes(elementsToExclude);
246 elementsToExclude.addAll(getSRLGList(service.get()));
247 LOG.info("readDiversity SRLG : {}", elementsToExclude);
248 if (elementsToExclude != null) {
249 constraints.setExcludeSrlgLinks(elementsToExclude);
253 /// Retrieve nodes into dedicated CLLI list
254 /// during node validation check their CLLI and build CLLI exclude list
255 elementsToExclude.addAll(getAToZNodeList(service.get()));
256 LOG.info("readDiversity CLLI : {}", elementsToExclude);
257 if (elementsToExclude != null) {
258 constraints.setExcludeClliNodes(elementsToExclude);
262 LOG.info("in readDiversity unsupported divercity type {}", rt);
266 LOG.info("in readDiversity srv={} is not present", srv);
272 private List<String> getAToZNodeList(PathDescription pathDescription) {
273 List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
274 return aendToZList.stream().filter(aToZ -> {
275 if (aToZ.getResource() == null || aToZ.getResource().getResource() == null) {
276 LOG.warn("Diversity constraint: Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
279 return aToZ.getResource().getResource() instanceof Node;
281 Node node = (Node) aToZ.getResource().getResource();
282 if (node.getNodeId() == null) {
283 LOG.warn("Node in AToZ node {} contains null! Skipping this node!", aToZ.getId());
288 Node node = ((Node) aToZ.getResource().getResource());
289 return node.getNodeId();
290 }).collect(Collectors.toList());
293 private List<String> getSRLGList(PathDescription pathDescription) {
294 List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
295 return aendToZList.stream().filter(aToZ -> {
296 if (aToZ.getResource() == null
297 || aToZ.getResource().getResource() == null) {
298 LOG.warn("Diversity constraint: Resource of AToZ {} is null! Skipping this resource!", aToZ.getId());
301 return aToZ.getResource().getResource() instanceof Link;
303 Link link = (Link) aToZ.getResource().getResource();
304 if (link.getLinkId() == null) {
305 LOG.warn("Link in AToZ link {} contains null! Skipping this link!", aToZ.getId());
310 return ((Link) aToZ.getResource().getResource()).getLinkId();
311 }).collect(Collectors.toList());
314 private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
315 Optional<PathDescription> result = Optional.empty();
316 InstanceIdentifier<ServicePaths> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
317 .child(ServicePaths.class, new ServicePathsKey(serviceName));
319 LOG.info("PCE diversity constraints: Getting path description for service {}", serviceName);
320 ServicePaths servicePaths =
321 networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
322 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).get();
323 if (servicePaths != null) {
324 PathDescription path = servicePaths.getPathDescription();
326 result = Optional.of(path);
329 } catch (InterruptedException | ExecutionException | TimeoutException e) {
331 "PCE diversity constraints: Exception while getting path description from datastore {} for service {}!",
332 pathDescriptionIID,serviceName, e);
338 private void readCoRoutingContrains(CoRouting tmpcoRouting, PceConstraints constraints) {
339 LOG.info("In readCoRoutingContrains start");
341 if (tmpcoRouting == null) {
342 LOG.info("In readCoRoutingContrains: no General constraints.");
347 public PceConstraints getPceHardConstraints() {
348 return pceHardConstraints;
351 public PceConstraints getPceSoftConstraints() {
352 return pceSoftConstraints;
355 public PceMetric getPceMetrics() {