aafdae1fb9ffa4c91c17f1a15a9b8a2509041e74
[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         List<NodeIdType> nodes = exclude.getNodeId();
115         if (nodes != null) {
116             List<String> elementsToExclude = new ArrayList<>();
117             for (NodeIdType node : nodes) {
118                 elementsToExclude.add(node.getValue());
119             }
120             constraints.setExcludeSupNodes(elementsToExclude);
121         }
122         List<Uint32> srlgs = exclude.getSrlgId();
123         if (srlgs != null) {
124             List<Long> elementsToExclude = new ArrayList<>();
125             for (Uint32 srlg : srlgs) {
126                 elementsToExclude.add(srlg.longValue());
127             }
128             constraints.setExcludeSRLG(elementsToExclude);
129         }
130         List<String> sites = exclude.getSite();
131         if (sites != null) {
132             constraints.setExcludeCLLI(exclude.getSite());
133         }
134         if (exclude.getFiberBundle() != null || exclude.getLinkIdentifier() != null
135             || exclude.getSupportingServiceName() != null) {
136             LOG.warn("exclude constraints of type fiber-bundle, link-identifier"
137                 + "or supporting-service-name are not implemented yet");
138         }
139     }
140
141     private void readInclude(Include include, PceConstraints constraints) {
142         List<NodeIdType> nodes = include.getNodeId();
143         if (nodes != null) {
144             for (NodeIdType node : nodes) {
145                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.NODE, node.getValue()));
146             }
147         }
148         List<Uint32> srlgs = include.getSrlgId();
149         if (srlgs != null) {
150             for (Uint32 srlg : srlgs) {
151                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.SRLG, srlg.toString()));
152             }
153         }
154         List<String> sites = include.getSite();
155         if (sites != null) {
156             for (String site : sites) {
157                 constraints.setListToInclude(new ResourcePair(PceConstraints.ResourceType.CLLI, site));
158             }
159         }
160     }
161
162     private void readCoRouting(CoRouting tmpcoRouting, PceConstraints constraints) {
163         if (tmpcoRouting == null) {
164             LOG.info("In readCoRoutingContrains: no CoRouting constraints.");
165         } else {
166             LOG.warn("CoRouting constraints handling not implemented yet");
167         }
168     }
169
170     private void readDiversity(Diversity diversity, PceConstraints constraints) {
171         //TODO: How to implement the DiversityType: serial or synchronous?
172         Map<ServiceIdentifierListKey, ServiceIdentifierList> serviceIdList = diversity.getServiceIdentifierList();
173         Collection<ServiceIdentifierList> services = serviceIdList.values();
174         for (ServiceIdentifierList serviceIdentifier : services) {
175             String serviceId = serviceIdentifier.getServiceIndentifier();
176             ServiceApplicability serviceApplicability = serviceIdentifier.getServiceApplicability();
177             Optional<PathDescription> serviceOpt = getPathDescriptionFromDatastore(serviceId);
178             if (serviceOpt.isPresent()) {
179                 List<String> serviceNodes = getAToZNodeList(serviceOpt.get());
180                 if (serviceApplicability.getNode() && !serviceNodes.isEmpty()) {
181                     constraints.setExcludeNodes(serviceNodes);
182                 }
183                 List<String> serviceLinks = getSRLGList(serviceOpt.get());
184                 if (serviceApplicability.getLink() && !serviceLinks.isEmpty()) {
185                     constraints.setExcludeSrlgLinks(serviceLinks);
186                 }
187                 if (serviceApplicability.getSite() && !serviceNodes.isEmpty()) {
188                     constraints.setExcludeClliNodes(serviceNodes);
189                 }
190             }
191         }
192     }
193
194     private List<String> getAToZNodeList(PathDescription pathDescription) {
195         List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
196         return aendToZList.stream().filter(aToZ -> {
197             if (aToZ.getResource() == null || aToZ.getResource().getResource() == null) {
198                 LOG.warn("Diversity constraint: Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
199                 return false;
200             }
201             return aToZ.getResource().getResource() instanceof Node;
202         }).filter(aToZ -> {
203             Node node = (Node) aToZ.getResource().getResource();
204             if (node.getNodeId() == null) {
205                 LOG.warn("Node in AToZ node {} contains null! Skipping this node!", aToZ.getId());
206                 return false;
207             }
208             return true;
209         }).map(aToZ -> {
210             Node node = ((Node) aToZ.getResource().getResource());
211             return node.getNodeId();
212         }).collect(Collectors.toList());
213     }
214
215     private List<String> getSRLGList(PathDescription pathDescription) {
216         List<AToZ> aendToZList = new ArrayList<>(pathDescription.getAToZDirection().nonnullAToZ().values());
217         return aendToZList.stream().filter(aToZ -> {
218             if (aToZ.getResource() == null
219                     || aToZ.getResource().getResource() == null) {
220                 LOG.warn("Diversity constraint: Resource of AToZ {} is null! Skipping this resource!", aToZ.getId());
221                 return false;
222             }
223             return aToZ.getResource().getResource() instanceof Link;
224         }).filter(aToZ -> {
225             Link link = (Link) aToZ.getResource().getResource();
226             if (link.getLinkId() == null) {
227                 LOG.warn("Link in AToZ link {} contains null! Skipping this link!", aToZ.getId());
228                 return false;
229             }
230             return true;
231         }).map(aToZ -> {
232             return ((Link) aToZ.getResource().getResource()).getLinkId();
233         }).collect(Collectors.toList());
234     }
235
236     private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
237         Optional<PathDescription> result = Optional.empty();
238         InstanceIdentifier<ServicePaths> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
239                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
240         try {
241             LOG.info("PCE diversity constraints: Getting path description for service {}", serviceName);
242             ServicePaths servicePaths =
243                 networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
244                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).get();
245             if (servicePaths != null) {
246                 PathDescription path = servicePaths.getPathDescription();
247                 if (path != null) {
248                     result = Optional.of(path);
249                 }
250             }
251         } catch (InterruptedException | ExecutionException | TimeoutException e) {
252             LOG.warn(
253                 "PCE diversity constraints: Exception while getting path description from datastore {} for service {}!",
254                 pathDescriptionIID,serviceName, e);
255             return result;
256         }
257         return result;
258     }
259
260     public PceConstraints getPceHardConstraints() {
261         return pceHardConstraints;
262     }
263
264     public PceConstraints getPceSoftConstraints() {
265         return pceSoftConstraints;
266     }
267
268     public PceMetric getPceMetrics() {
269         return pceMetrics;
270     }
271
272 }