PCE module init
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / PceConstraintsCalc.java
1 /*
2  * Copyright © 2017 AT&T, 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 package org.opendaylight.transportpce.pce;
9
10 import com.google.common.base.Optional;
11
12 import java.util.ArrayList;
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
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.Timeouts;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev170426.PathComputationRequestInput;
25 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.node.NodeIdentifier;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.RoutingConstraintsSp.PceMetric;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.CoRoutingOrGeneral;
30 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.CoRouting;
31 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.General;
32 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Diversity;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Exclude;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Latency;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraints;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraints;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.PathDescription;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathList;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePaths;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsKey;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class PceConstraintsCalc {
46     /* Logging. */
47     private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
48
49     private PceConstraints pceHardConstraints = new PceConstraints();
50     private PceConstraints pceSoftConstraints = new PceConstraints();
51     private PceMetric pceMetrics = PceMetric.HopCount;
52     private DataBroker dataBroker;
53
54
55     public PceConstraintsCalc(PathComputationRequestInput input, DataBroker dataBroker) {
56         LOG.debug("In PceconstraintsCalc start");
57
58         this.pceMetrics = input.getPceMetric();
59
60         this.dataBroker = dataBroker;
61
62         // TODO. for now metrics are set into hard structure
63         LOG.info("In PceConstraintsCalc: read PceMetric {}", this.pceMetrics.toString());
64         this.pceHardConstraints.setPceMetrics(this.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, this.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, this.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.toString());
107             tmpGeneral = (General) coRoutingOrGeneral;
108             readGeneralContrains(tmpGeneral, constraints);
109             return;
110         }
111
112         if (coRoutingOrGeneral instanceof CoRouting) {
113             LOG.info("In readconstraints CoRouting {}", coRoutingOrGeneral.toString());
114             tmpCoRouting = (CoRouting) coRoutingOrGeneral;
115             readCoRoutingContrains(tmpCoRouting, constraints);
116             return;
117         }
118
119         return;
120
121     }
122
123     private void readGeneralContrains(General tmpGeneral, PceConstraints constraints) {
124         LOG.debug("In readGeneralContrains start");
125
126         if (tmpGeneral  ==  null) {
127             LOG.info("In readGeneralContrains: no General constraints.");
128             return;
129         }
130
131         Latency latency = tmpGeneral.getLatency();
132         if (latency != null) {
133             constraints.setMaxLatency(latency.getMaxLatency());
134             LOG.info("In readGeneralContrains: read latency {}", latency.toString());
135         }
136
137         Exclude exclude = tmpGeneral.getExclude();
138         List<String> elementsToExclude = null;
139         if (exclude != null) {
140             elementsToExclude = exclude.getNodeId();
141             if (elementsToExclude != null) {
142                 constraints.setExcludeNodes(elementsToExclude);
143             }
144             elementsToExclude = exclude.getSRLG();
145             if (elementsToExclude != null) {
146                 constraints.setExcludeSRLG(elementsToExclude);
147             }
148         }
149
150         Diversity diversity = tmpGeneral.getDiversity();
151         if (diversity != null) {
152             if (diversity.getExistingServiceApplicability().isNode()) {
153                 LOG.info("in readGeneralContrains {}", diversity.toString());
154                 readDiversityNodes(diversity.getExistingService(), constraints);
155             }
156         }
157
158     }
159
160     private void readDiversityNodes(List<String> srvList, PceConstraints constraints) {
161
162         List<String> elementsToExclude = new ArrayList<String>();
163         LOG.info("in readDiversityNodes {}", srvList.toString());
164
165         for (String srv : srvList) {
166             Optional<PathDescription> service = getPathDescriptionFromDatastore(srv);
167             if (service.isPresent()) {
168                 elementsToExclude.addAll(getAToZNodeList(service.get()));
169                 LOG.info("readDiversityNodes : {}", elementsToExclude);
170
171             } else {
172                 LOG.info("in readDiversityNodes srv={} is not present", srv);
173             }
174         }
175
176         if (elementsToExclude != null) {
177             constraints.setExcludeNodes(elementsToExclude);
178         }
179     }
180
181     private List<String> getAToZNodeList(PathDescription pathDescription) {
182         List<AToZ> atozList = pathDescription.getAToZDirection().getAToZ();
183         return atozList.stream().filter(aToZ -> {
184             if ((aToZ.getResource() == null) || (aToZ.getResource().getResource() == null)) {
185                 LOG.warn("Diversity constraint: Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
186                 return false;
187             }
188             return aToZ.getResource().getResource() instanceof Node;
189         }).filter(aToZ -> {
190             Node node = (Node) aToZ.getResource().getResource();
191             if (node.getNodeIdentifier() == null) {
192                 LOG.warn("Node in AToZ node {} contains null! Skipping this node!", aToZ.getId());
193                 return false;
194             }
195             return true;
196         }).map(aToZ -> {
197             NodeIdentifier node = ((Node) aToZ.getResource().getResource()).getNodeIdentifier();
198             return node.getNodeId().toString();
199         }).collect(Collectors.toList());
200     }
201
202     private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
203         InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
204                 .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
205         ReadOnlyTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
206         try {
207             LOG.info("PCE diversity constraints: Getting path description for service {}", serviceName);
208             return pathDescReadTx.read(LogicalDatastoreType.CONFIGURATION, pathDescriptionIID)
209                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
210         } catch (InterruptedException | ExecutionException | TimeoutException e) {
211             LOG.warn(
212                 "PCE diversity constraints: Exception while getting path description from datastore {} for service {}!",
213                 pathDescriptionIID,serviceName, e);
214             return Optional.absent();
215         }
216     }
217
218     private void readCoRoutingContrains(CoRouting tmpcoRouting, PceConstraints constraints) {
219         LOG.info("In readCoRoutingContrains start");
220
221         if (tmpcoRouting  ==  null) {
222             LOG.info("In readCoRoutingContrains: no General constraints.");
223             return;
224         }
225
226     }
227
228     public PceConstraints getPceHardConstraints() {
229         return this.pceHardConstraints;
230     }
231
232     public PceConstraints getPceSoftConstraints() {
233         return this.pceSoftConstraints;
234     }
235
236     public PceMetric getPceMetrics() {
237         return this.pceMetrics;
238     }
239
240
241 }