Adapt TransportPCE code to Sulfur
[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.Collection;
12 import java.util.List;
13 import java.util.Map;
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.transportpce.pce.constraints.PceConstraints.ResourcePair;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220615.PathComputationRequestInput;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev210528.NodeIdType;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.Constraints;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.CoRouting;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.Diversity;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.Exclude;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.Include;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.diversity.existing.service.constraints.ServiceIdentifierList;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.diversity.existing.service.constraints.ServiceIdentifierListKey;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.routing.constraints.HardConstraints;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.routing.constraints.SoftConstraints;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.service.applicability.g.ServiceApplicability;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.PathDescription;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.Link;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.Node;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.PceMetric;
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.opendaylight.yangtools.yang.common.Uint32;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48
49 public class PceConstraintsCalc {
50     /* Logging. */
51     private static final Logger LOG = LoggerFactory.getLogger(PceConstraintsCalc.class);
52
53     private PceConstraints pceHardConstraints = new PceConstraints();
54     private PceConstraints pceSoftConstraints = new PceConstraints();
55     private PceMetric pceMetrics = PceMetric.HopCount;
56     private NetworkTransactionService networkTransactionService;
57
58     public PceConstraintsCalc(PathComputationRequestInput input, NetworkTransactionService networkTransactionService) {
59         LOG.debug("In PceconstraintsCalc start");
60
61         pceMetrics = input.getPceRoutingMetric();
62
63         this.networkTransactionService = networkTransactionService;
64
65         // TODO. for now metrics are set into hard structure
66         LOG.info("In PceConstraintsCalc: read PceMetric {}", pceMetrics);
67         pceHardConstraints.setPceMetrics(pceMetrics);
68
69         calcHardconstraints(input);
70         calcSoftconstraints(input);
71     }
72
73     private void calcHardconstraints(PathComputationRequestInput input) {
74         HardConstraints servicePathHardConstraints = input.getHardConstraints();
75         if (servicePathHardConstraints == null) {
76             LOG.info("In calcHardconstraints: no hard constraints.");
77             return;
78         }
79         readConstraints(servicePathHardConstraints, pceHardConstraints);
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         readConstraints(servicePathSoftConstraints, pceSoftConstraints);
89     }
90
91     private void readConstraints(Constraints hardConstraints, PceConstraints constraints) {
92         LOG.debug("In readHardconstraints start");
93
94         if (hardConstraints.getInclude() != null) {
95             readInclude(hardConstraints.getInclude(), constraints);
96         }
97         if (hardConstraints.getExclude() != null) {
98             readExclude(hardConstraints.getExclude(), constraints);
99         }
100         if (hardConstraints.getCoRouting() != null) {
101             readCoRouting(hardConstraints.getCoRouting(), constraints);
102         }
103         if (hardConstraints.getDiversity() != null) {
104             readDiversity(hardConstraints.getDiversity(), constraints);
105         }
106         if (hardConstraints.getLatency() != null) {
107             constraints.setMaxLatency(hardConstraints.getLatency().getMaxLatency().longValue());
108         }
109     }
110
111     private void readExclude(Exclude exclude, PceConstraints constraints) {
112         //TODO: Implement other exclude constraints: fiber-bundle, link-identifier
113         // and supporting-service-name
114         if (exclude.getNodeId() != null) {
115             List<String> elementsToExclude = new ArrayList<>();
116             for (NodeIdType node : exclude.getNodeId()) {
117                 elementsToExclude.add(node.getValue());
118             }
119             constraints.setExcludeSupNodes(elementsToExclude);
120         }
121         if (exclude.getSrlgId() != null) {
122             List<Long> elementsToExclude = new ArrayList<>();
123             for (Uint32 srlg : exclude.getSrlgId()) {
124                 elementsToExclude.add(srlg.longValue());
125             }
126             constraints.setExcludeSRLG(elementsToExclude);
127         }
128         if (exclude.getSite() != null) {
129             constraints.setExcludeCLLI(new ArrayList<>(exclude.getSite()));
130         }
131         if (exclude.getFiberBundle() != null || exclude.getLinkIdentifier() != null
132             || exclude.getSupportingServiceName() != null) {
133             LOG.warn("exclude constraints of type fiber-bundle, link-identifier"
134                 + "or supporting-service-name are not implemented yet");
135         }
136     }
137
138     private void readInclude(Include include, PceConstraints constraints) {
139         if (include.getNodeId() != null) {
140             for (NodeIdType node : include.getNodeId()) {
141                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.NODE, node.getValue()));
142             }
143         }
144         if (include.getSrlgId() != null) {
145             for (Uint32 srlg : include.getSrlgId()) {
146                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.SRLG, srlg.toString()));
147             }
148         }
149         if (include.getSite() != null) {
150             for (String site : include.getSite()) {
151                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.CLLI, site));
152             }
153         }
154     }
155
156     private void readCoRouting(CoRouting tmpcoRouting, PceConstraints constraints) {
157         if (tmpcoRouting == null) {
158             LOG.info("In readCoRoutingContrains: no CoRouting constraints.");
159         } else {
160             LOG.warn("CoRouting constraints handling not implemented yet");
161         }
162     }
163
164     private void readDiversity(Diversity diversity, PceConstraints constraints) {
165         //TODO: How to implement the DiversityType: serial or synchronous?
166         Map<ServiceIdentifierListKey, ServiceIdentifierList> serviceIdList = diversity.getServiceIdentifierList();
167         Collection<ServiceIdentifierList> services = serviceIdList.values();
168         for (ServiceIdentifierList serviceIdentifier : services) {
169             String serviceId = serviceIdentifier.getServiceIndentifier();
170             ServiceApplicability serviceApplicability = serviceIdentifier.getServiceApplicability();
171             Optional<PathDescription> serviceOpt = getPathDescriptionFromDatastore(serviceId);
172             if (serviceOpt.isPresent()) {
173                 List<String> serviceNodes = getAToZNodeList(serviceOpt.get());
174                 if (serviceApplicability.getNode() && !serviceNodes.isEmpty()) {
175                     constraints.setExcludeNodes(serviceNodes);
176                 }
177                 List<String> serviceLinks = getSRLGList(serviceOpt.get());
178                 if (serviceApplicability.getLink() && !serviceLinks.isEmpty()) {
179                     constraints.setExcludeSrlgLinks(serviceLinks);
180                 }
181                 if (serviceApplicability.getSite() && !serviceNodes.isEmpty()) {
182                     constraints.setExcludeClliNodes(serviceNodes);
183                 }
184             }
185         }
186     }
187
188     private List<String> getAToZNodeList(PathDescription pathDescription) {
189         List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
190         return aendToZList.stream().filter(aToZ -> {
191             if (aToZ.getResource() == null || aToZ.getResource().getResource() == null) {
192                 LOG.warn("Diversity constraint: Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
193                 return false;
194             }
195             return aToZ.getResource().getResource() instanceof Node;
196         }).filter(aToZ -> {
197             Node node = (Node) aToZ.getResource().getResource();
198             if (node.getNodeId() == null) {
199                 LOG.warn("Node in AToZ node {} contains null! Skipping this node!", aToZ.getId());
200                 return false;
201             }
202             return true;
203         }).map(aToZ -> {
204             Node node = ((Node) aToZ.getResource().getResource());
205             return node.getNodeId();
206         }).collect(Collectors.toList());
207     }
208
209     private List<String> getSRLGList(PathDescription pathDescription) {
210         List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
211         return aendToZList.stream().filter(aToZ -> {
212             if (aToZ.getResource() == null
213                     || aToZ.getResource().getResource() == null) {
214                 LOG.warn("Diversity constraint: Resource of AToZ {} is null! Skipping this resource!", aToZ.getId());
215                 return false;
216             }
217             return aToZ.getResource().getResource() instanceof Link;
218         }).filter(aToZ -> {
219             Link link = (Link) aToZ.getResource().getResource();
220             if (link.getLinkId() == null) {
221                 LOG.warn("Link in AToZ link {} contains null! Skipping this link!", aToZ.getId());
222                 return false;
223             }
224             return true;
225         }).map(aToZ -> {
226             return ((Link) aToZ.getResource().getResource()).getLinkId();
227         }).collect(Collectors.toList());
228     }
229
230     private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
231         Optional<PathDescription> result = Optional.empty();
232         InstanceIdentifier<ServicePaths> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
233                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
234         try {
235             LOG.info("PCE diversity constraints: Getting path description for service {}", serviceName);
236             ServicePaths servicePaths =
237                 networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
238                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).get();
239             if (servicePaths != null) {
240                 PathDescription path = servicePaths.getPathDescription();
241                 if (path != null) {
242                     result = Optional.of(path);
243                 }
244             }
245         } catch (InterruptedException | ExecutionException | TimeoutException e) {
246             LOG.warn(
247                 "PCE diversity constraints: Exception while getting path description from datastore {} for service {}!",
248                 pathDescriptionIID,serviceName, e);
249             return result;
250         }
251         return result;
252     }
253
254     public PceConstraints getPceHardConstraints() {
255         return pceHardConstraints;
256     }
257
258     public PceConstraints getPceSoftConstraints() {
259         return pceSoftConstraints;
260     }
261
262     public PceMetric getPceMetrics() {
263         return pceMetrics;
264     }
265
266 }