blob: e7ef93540389bc3ff149035c21e58992494d252e [file] [log] [blame]
Avantika-Huawei73862d42016-05-12 18:58:06 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Avantika-Huawei73862d42016-05-12 18:58:06 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.pce.pceservice;
17
18import static com.google.common.base.Preconditions.checkNotNull;
Avantika-Huawei73862d42016-05-12 18:58:06 +053019
Ray Milkeya7cf8c82018-02-08 15:07:06 -080020import org.onlab.graph.ScalarWeight;
Ray Milkey7483e1b2018-02-07 15:43:01 -080021import org.onlab.graph.Weight;
Satish Kba1c9122017-04-05 15:27:23 +053022import org.onosproject.net.DisjointPath;
Satish K2eb5d842017-04-04 16:28:37 +053023import java.util.ArrayList;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053024import java.util.Collection;
Priyanka Bb6963582016-05-20 20:21:20 +053025import java.util.Collections;
Satish K2eb5d842017-04-04 16:28:37 +053026import java.util.HashMap;
Avantika-Huawei73862d42016-05-12 18:58:06 +053027import java.util.Iterator;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053028import java.util.LinkedList;
Avantika-Huawei73862d42016-05-12 18:58:06 +053029import java.util.List;
Satish K2eb5d842017-04-04 16:28:37 +053030import java.util.Map;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053031import java.util.Optional;
Priyanka Bb6963582016-05-20 20:21:20 +053032import java.util.Set;
Avantika-Huawei73862d42016-05-12 18:58:06 +053033import org.apache.felix.scr.annotations.Activate;
34import org.apache.felix.scr.annotations.Component;
35import org.apache.felix.scr.annotations.Deactivate;
36import org.apache.felix.scr.annotations.Reference;
37import org.apache.felix.scr.annotations.ReferenceCardinality;
38import org.apache.felix.scr.annotations.Service;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053039import org.onlab.packet.IpAddress;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053040import org.onlab.util.Bandwidth;
Avantika-Huawei73862d42016-05-12 18:58:06 +053041import org.onosproject.core.ApplicationId;
42import org.onosproject.core.CoreService;
43import org.onosproject.core.IdGenerator;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053044import org.onosproject.incubator.net.tunnel.DefaultTunnel;
45import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
Avantika-Huawei73862d42016-05-12 18:58:06 +053046import org.onosproject.incubator.net.tunnel.Tunnel;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053047import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
48import org.onosproject.incubator.net.tunnel.TunnelEvent;
Avantika-Huawei73862d42016-05-12 18:58:06 +053049import org.onosproject.incubator.net.tunnel.TunnelId;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053050import org.onosproject.incubator.net.tunnel.TunnelListener;
51import org.onosproject.incubator.net.tunnel.TunnelName;
Avantika-Huawei73862d42016-05-12 18:58:06 +053052import org.onosproject.incubator.net.tunnel.TunnelService;
Priyanka B3f92c5a2016-05-27 10:14:16 +053053import org.onosproject.mastership.MastershipService;
Satish K2eb5d842017-04-04 16:28:37 +053054import org.onosproject.net.LinkKey;
55import org.onosproject.net.config.ConfigFactory;
56import org.onosproject.net.config.NetworkConfigRegistry;
Avantika-Huawei032a9872016-05-27 22:57:38 +053057import org.onosproject.net.config.NetworkConfigService;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053058import org.onosproject.net.DefaultAnnotations;
59import org.onosproject.net.DefaultAnnotations.Builder;
Priyanka Bbae0eeb12016-11-30 11:59:48 +053060import org.onosproject.net.DefaultPath;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053061import org.onosproject.net.Device;
Avantika-Huawei73862d42016-05-12 18:58:06 +053062import org.onosproject.net.DeviceId;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053063import org.onosproject.net.Link;
Priyanka Bbae0eeb12016-11-30 11:59:48 +053064import org.onosproject.net.NetworkResource;
Priyanka Bb6963582016-05-20 20:21:20 +053065import org.onosproject.net.Path;
Satish K2eb5d842017-04-04 16:28:37 +053066import org.onosproject.net.config.basics.SubjectFactories;
Priyanka Bb6963582016-05-20 20:21:20 +053067import org.onosproject.net.device.DeviceService;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053068import org.onosproject.net.intent.Constraint;
Priyanka B3f92c5a2016-05-27 10:14:16 +053069import org.onosproject.net.link.LinkEvent;
Mahesh Poojary Huawei1d17cad2016-06-02 12:53:41 +053070import org.onosproject.net.MastershipRole;
Satish K2eb5d842017-04-04 16:28:37 +053071import org.onosproject.bandwidthmgr.api.BandwidthMgmtService;
Ray Milkey7483e1b2018-02-07 15:43:01 -080072import org.onosproject.net.topology.LinkWeigher;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053073import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
74import org.onosproject.pce.pceservice.constraint.CapabilityConstraint.CapabilityType;
75import org.onosproject.pce.pceservice.constraint.CostConstraint;
Satish K2eb5d842017-04-04 16:28:37 +053076import org.onosproject.pce.pceservice.constraint.PceBandwidthConstraint;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053077import org.onosproject.pce.pceservice.constraint.SharedBandwidthConstraint;
78import org.onosproject.net.resource.Resource;
79import org.onosproject.net.resource.ResourceAllocation;
Priyanka Bb6963582016-05-20 20:21:20 +053080import org.onosproject.net.topology.PathService;
81import org.onosproject.net.topology.TopologyEdge;
Priyanka B3f92c5a2016-05-27 10:14:16 +053082import org.onosproject.net.topology.TopologyEvent;
83import org.onosproject.net.topology.TopologyListener;
84import org.onosproject.net.topology.TopologyService;
Avantika-Huawei73862d42016-05-12 18:58:06 +053085import org.onosproject.pce.pceservice.api.PceService;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053086import org.onosproject.pce.pcestore.PcePathInfo;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053087import org.onosproject.pce.pcestore.api.PceStore;
Avantika-Huawei032a9872016-05-27 22:57:38 +053088import org.onosproject.pcep.api.DeviceCapability;
Satish K2eb5d842017-04-04 16:28:37 +053089import org.onosproject.pcep.api.TeLinkConfig;
Avantika-Huawei73862d42016-05-12 18:58:06 +053090import org.onosproject.store.serializers.KryoNamespaces;
91import org.onosproject.store.service.DistributedSet;
92import org.onosproject.store.service.Serializer;
93import org.onosproject.store.service.StorageService;
94import org.slf4j.Logger;
95import org.slf4j.LoggerFactory;
96
Priyanka Bb6963582016-05-20 20:21:20 +053097import com.google.common.collect.ImmutableList;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +053098import com.google.common.collect.ImmutableSet;
Priyanka Bbae0eeb12016-11-30 11:59:48 +053099import com.google.common.collect.Sets;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530100
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530101import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530102import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
Priyanka B4c3b4512016-07-22 11:41:49 +0530103import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530104import static org.onosproject.pce.pceservice.LspType.WITH_SIGNALLING;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530105import static org.onosproject.pce.pceservice.PcepAnnotationKeys.BANDWIDTH;
106import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
107import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LSP_SIG_TYPE;
108import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PCE_INIT;
109import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
110import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PCC_TUNNEL_ID;
111import static org.onosproject.pce.pceservice.PcepAnnotationKeys.DELEGATE;
112import static org.onosproject.pce.pceservice.PcepAnnotationKeys.COST_TYPE;
113
Avantika-Huawei73862d42016-05-12 18:58:06 +0530114/**
115 * Implementation of PCE service.
116 */
117@Component(immediate = true)
118@Service
119public class PceManager implements PceService {
120 private static final Logger log = LoggerFactory.getLogger(PceManager.class);
121
Mahesh Poojary Huawei1d17cad2016-06-02 12:53:41 +0530122 public static final long GLOBAL_LABEL_SPACE_MIN = 4097;
123 public static final long GLOBAL_LABEL_SPACE_MAX = 5121;
Avantika-Huawei73862d42016-05-12 18:58:06 +0530124 public static final String PCE_SERVICE_APP = "org.onosproject.pce";
Avantika-Huawei73862d42016-05-12 18:58:06 +0530125 private static final String LOCAL_LSP_ID_GEN_TOPIC = "pcep-local-lsp-id";
Mahesh Poojary Huawei1d17cad2016-06-02 12:53:41 +0530126 public static final String DEVICE_TYPE = "type";
127 public static final String L3_DEVICE = "L3";
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530128
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530129 private static final String LSRID = "lsrId";
130 private static final String TRUE = "true";
131 private static final String FALSE = "false";
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530132 public static final int PCEP_PORT = 4189;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530133
Avantika-Huawei73862d42016-05-12 18:58:06 +0530134 private IdGenerator localLspIdIdGen;
135 protected DistributedSet<Short> localLspIdFreeList;
136
137 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
138 protected CoreService coreService;
139
140 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530141 protected PathService pathService;
142
143 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
144 protected PceStore pceStore;
145
146 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Avantika-Huawei73862d42016-05-12 18:58:06 +0530147 protected TunnelService tunnelService;
148
149 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Priyanka Bb6963582016-05-20 20:21:20 +0530150 protected DeviceService deviceService;
151
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530152 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530153 protected StorageService storageService;
Mahesh Poojary Huawei1d17cad2016-06-02 12:53:41 +0530154
155 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Avantika-Huawei032a9872016-05-27 22:57:38 +0530156 protected NetworkConfigService netCfgService;
157
158 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Priyanka B3f92c5a2016-05-27 10:14:16 +0530159 protected MastershipService mastershipService;
160
161 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
162 protected TopologyService topologyService;
163
Satish K2eb5d842017-04-04 16:28:37 +0530164 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
165 protected BandwidthMgmtService bandwidthMgmtService;
166
167 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
168 protected NetworkConfigRegistry netConfigRegistry;
169
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530170 private TunnelListener listener = new InnerTunnelListener();
Avantika-Huawei73862d42016-05-12 18:58:06 +0530171 private ApplicationId appId;
172
Priyanka B3f92c5a2016-05-27 10:14:16 +0530173 private final TopologyListener topologyListener = new InternalTopologyListener();
Satish Kba1c9122017-04-05 15:27:23 +0530174 public static final String LOAD_BALANCING_PATH_NAME = "loadBalancingPathName";
Priyanka B9fa4ed32016-05-27 11:59:24 +0530175
Satish K2eb5d842017-04-04 16:28:37 +0530176 private List<TunnelId> rsvpTunnelsWithLocalBw = new ArrayList<>();
177
178 private final ConfigFactory<LinkKey, TeLinkConfig> configFactory =
179 new ConfigFactory<LinkKey, TeLinkConfig>(SubjectFactories.LINK_SUBJECT_FACTORY,
180 TeLinkConfig.class, "teLinkConfig") {
181 @Override
182 public TeLinkConfig createConfig() {
183 return new TeLinkConfig();
184 }
185 };
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530186
Avantika-Huawei73862d42016-05-12 18:58:06 +0530187 /**
188 * Creates new instance of PceManager.
189 */
190 public PceManager() {
191 }
192
193 @Activate
194 protected void activate() {
195 appId = coreService.registerApplication(PCE_SERVICE_APP);
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530196
197 tunnelService.addListener(listener);
198
Avantika-Huawei73862d42016-05-12 18:58:06 +0530199 localLspIdIdGen = coreService.getIdGenerator(LOCAL_LSP_ID_GEN_TOPIC);
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530200 localLspIdIdGen.getNewId(); // To prevent 0, the 1st value generated from being used in protocol.
Avantika-Huawei73862d42016-05-12 18:58:06 +0530201 localLspIdFreeList = storageService.<Short>setBuilder()
202 .withName("pcepLocalLspIdDeletedList")
203 .withSerializer(Serializer.using(KryoNamespaces.API))
204 .build()
205 .asDistributedSet();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530206
Priyanka B3f92c5a2016-05-27 10:14:16 +0530207 topologyService.addListener(topologyListener);
Satish K2eb5d842017-04-04 16:28:37 +0530208 netConfigRegistry.registerConfigFactory(configFactory);
Mahesh Poojary Huawei1d17cad2016-06-02 12:53:41 +0530209
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530210 log.info("Started");
Avantika-Huawei73862d42016-05-12 18:58:06 +0530211 }
212
213 @Deactivate
214 protected void deactivate() {
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530215 tunnelService.removeListener(listener);
Priyanka B3f92c5a2016-05-27 10:14:16 +0530216 topologyService.removeListener(topologyListener);
Satish K2eb5d842017-04-04 16:28:37 +0530217 netConfigRegistry.unregisterConfigFactory(configFactory);
218
Avantika-Huawei73862d42016-05-12 18:58:06 +0530219 log.info("Stopped");
220 }
221
Priyanka Bb6963582016-05-20 20:21:20 +0530222 /**
223 * Returns an edge-weight capable of evaluating links on the basis of the
224 * specified constraints.
225 *
226 * @param constraints path constraints
227 * @return edge-weight function
228 */
Ray Milkey7483e1b2018-02-07 15:43:01 -0800229 private LinkWeigher weight(List<Constraint> constraints) {
Priyanka Bb6963582016-05-20 20:21:20 +0530230 return new TeConstraintBasedLinkWeight(constraints);
231 }
232
233 /**
234 * Computes a path between two devices.
235 *
236 * @param src ingress device
237 * @param dst egress device
238 * @param constraints path constraints
239 * @return computed path based on constraints
240 */
241 protected Set<Path> computePath(DeviceId src, DeviceId dst, List<Constraint> constraints) {
242 if (pathService == null) {
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530243 return ImmutableSet.of();
Priyanka Bb6963582016-05-20 20:21:20 +0530244 }
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530245
Priyanka Bb6963582016-05-20 20:21:20 +0530246 Set<Path> paths = pathService.getPaths(src, dst, weight(constraints));
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530247 log.info("paths in computePath ::" + paths);
Priyanka Bb6963582016-05-20 20:21:20 +0530248 if (!paths.isEmpty()) {
249 return paths;
250 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530251 return ImmutableSet.of();
Priyanka Bb6963582016-05-20 20:21:20 +0530252 }
253
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530254 //Computes the partial path from partial computed path to specified dst.
255 private List<Path> computePartialPath(List<Path> computedPath, DeviceId src, DeviceId dst,
256 List<Constraint> constraints) {
257 int size = computedPath.size();
258 Path path = null;
259 DeviceId deviceId = size == 0 ? src :
260 computedPath.get(size - 1).dst().deviceId();
261
262 Set<Path> tempComputePath = computePath(deviceId, dst, constraints);
263
264 if (tempComputePath.isEmpty()) {
265 return null;
266 }
267
268 //if path validation fails return null
269 //Validate computed path to avoid loop in the path
270 for (Path p : tempComputePath) {
271 if (pathValidation(computedPath, p)) {
272 path = p;
273 break;
274 }
275 }
276 if (path == null) {
277 return null;
278 }
279
280 //Store the partial path result in a list
281 computedPath.add(path);
282 return computedPath;
283 }
284
285 private List<DeviceId> createListOfDeviceIds(List<? extends NetworkResource> list) {
286 List<Link> links = new LinkedList<>();
287 if (!list.isEmpty() && list.iterator().next() instanceof Path) {
288 for (Path path : (List<Path>) list) {
289 links.addAll(path.links());
290 }
291 } else if (!list.isEmpty() && list.iterator().next() instanceof Link) {
292 links.addAll((List<Link>) list);
293 }
294
295 //List of devices for new path computed
296 DeviceId source = null;
297 DeviceId destination = null;
298 List<DeviceId> devList = new LinkedList<>();
299
300 for (Link l : links) {
301 if (!devList.contains(l.src().deviceId())) {
302 devList.add(l.src().deviceId());
303 }
304 if (!devList.contains(l.dst().deviceId())) {
305 devList.add(l.dst().deviceId());
306 }
307 }
308
309 return devList;
310 }
311
Ray Milkeyc108a6b2017-08-23 15:23:50 -0700312 //To detect loops in the path i.e if the partial paths has intersection node avoid it.
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530313 private boolean pathValidation(List<Path> partialPath, Path path) {
314
315 //List of devices in new path computed
316 List<DeviceId> newPartialPathDevList;
317 newPartialPathDevList = createListOfDeviceIds(path.links());
318
319 //List of devices in partial computed path
320 List<DeviceId> partialComputedPathDevList;
321 partialComputedPathDevList = createListOfDeviceIds(partialPath);
322
323 for (DeviceId deviceId : newPartialPathDevList) {
324 for (DeviceId devId : partialComputedPathDevList) {
325 if (!newPartialPathDevList.get(0).equals(deviceId) &&
326 !partialComputedPathDevList.get(partialComputedPathDevList.size() - 1).equals(devId)
327 && deviceId.equals(devId)) {
328 return false;
329 }
330 }
331 }
332 return true;
333 }
334
335 //Returns final computed explicit path (list of partial computed paths).
336 private List<Path> computeExplicitPath(List<ExplicitPathInfo> explicitPathInfo, DeviceId src, DeviceId dst,
337 List<Constraint> constraints) {
338 List<Path> finalComputedPath = new LinkedList<>();
339 for (ExplicitPathInfo info : explicitPathInfo) {
340 /*
341 * If explicit path object is LOOSE,
342 * 1) If specified as DeviceId (node) :
343 * If it is source , compute from source to destination (partial computation not required),
344 * otherwise compute from specified source to specified device
345 * 2) If specified as Link :
346 * Compute partial path from source to link's source , if path exists compute from link's source to dst
347 */
348 if (info.type().equals(ExplicitPathInfo.Type.LOOSE)) {
349 if (info.value() instanceof DeviceId) {
350 // If deviceId is source no need to compute
351 if (!(info.value()).equals(src)) {
352 log.debug("computeExplicitPath :: Loose , device");
353 finalComputedPath = computePartialPath(finalComputedPath, src, (DeviceId) info.value(),
354 constraints);
355 log.debug("finalComputedPath in computeExplicitPath ::" + finalComputedPath);
356 }
357
358 } else if (info.value() instanceof Link) {
359 if ((((Link) info.value()).src().deviceId().equals(src))
360 || (!finalComputedPath.isEmpty()
361 && finalComputedPath.get(finalComputedPath.size() - 1).dst().deviceId().equals(
362 ((Link) info.value()).src().deviceId()))) {
363
364 finalComputedPath = computePartialPath(finalComputedPath, src, ((Link) info.value()).dst()
365 .deviceId(), constraints);
366 } else {
367
368 finalComputedPath = computePartialPath(finalComputedPath, src, ((Link) info.value()).src()
369 .deviceId(), constraints) != null ? computePartialPath(finalComputedPath, src,
370 ((Link) info.value()).dst().deviceId(), constraints) : null;
371 }
372 }
373 /*
374 * If explicit path object is STRICT,
375 * 1) If specified as DeviceId (node) :
376 * Check whether partial computed path has reachable to strict specified node orde
377 * strict node is the source, if no set path as null else do nothing
378 * 2) If specified as Link :
379 * Check whether partial computed path has reachable to strict link's src, if yes compute
380 * path from strict link's src to link's dst (to include specified link)
381 */
382 } else if (info.type().equals(ExplicitPathInfo.Type.STRICT)) {
383 if (info.value() instanceof DeviceId) {
384 log.debug("computeExplicitPath :: Strict , device");
385 if (!(!finalComputedPath.isEmpty() && finalComputedPath.get(finalComputedPath.size() - 1).dst()
386 .deviceId().equals(info.value()))
387 && !info.value().equals(src)) {
388 finalComputedPath = null;
389 }
390
391 } else if (info.value() instanceof Link) {
392 log.info("computeExplicitPath :: Strict");
393 finalComputedPath = ((Link) info.value()).src().deviceId().equals(src)
394 || !finalComputedPath.isEmpty()
395 && finalComputedPath.get(finalComputedPath.size() - 1).dst().deviceId()
396 .equals(((Link) info.value()).src().deviceId()) ? computePartialPath(
397 finalComputedPath, src, ((Link) info.value()).dst().deviceId(), constraints) : null;
398
399 //Log.info("computeExplicitPath :: (Link) info.value() " + (Link) info.value());
400 //Log.info("computeExplicitPath :: finalComputedPath " + finalComputedPath);
401
402 if (finalComputedPath != null && !finalComputedPath.get(finalComputedPath.size() - 1).links()
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800403 .contains(info.value())) {
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530404 finalComputedPath = null;
405 }
406 }
407 }
408 if (finalComputedPath == null) {
409 return null;
410 }
411 }
412 // Destination is not reached in Partial computed path then compute till destination
413 if (finalComputedPath.isEmpty() || !finalComputedPath.isEmpty()
414 && !finalComputedPath.get(finalComputedPath.size() - 1).dst().deviceId().equals(dst)) {
415
416 finalComputedPath = computePartialPath(finalComputedPath, src, dst, constraints);
417 if (finalComputedPath == null) {
418 return null;
419 }
420 }
421
422 return finalComputedPath;
423 }
424
Priyanka Ba32f6da2016-09-02 16:10:21 +0530425 @Override
426 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
Priyankab-Huawei3946d732016-10-11 06:24:38 +0000427 LspType lspType) {
Satish Kba1c9122017-04-05 15:27:23 +0530428 return setupPath(src, dst, tunnelName, constraints, lspType, null, false);
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530429 }
430
431 //[TODO:] handle requests in queue
432 @Override
433 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
434 LspType lspType, List<ExplicitPathInfo> explicitPathInfo) {
Satish Kba1c9122017-04-05 15:27:23 +0530435 return setupPath(src, dst, tunnelName, constraints, lspType, explicitPathInfo, false);
436
437 }
438
439 @Override
440 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
441 LspType lspType, boolean loadBalancing) {
442 return setupPath(src, dst, tunnelName, constraints, lspType, null, loadBalancing);
443 }
444
445 @Override
446 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
447 LspType lspType, List<ExplicitPathInfo> explicitPathInfo, boolean loadBalancing) {
Avantika-Huawei73862d42016-05-12 18:58:06 +0530448 checkNotNull(src);
449 checkNotNull(dst);
450 checkNotNull(tunnelName);
Avantika-Huawei73862d42016-05-12 18:58:06 +0530451 checkNotNull(lspType);
452
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530453 // Convert from DeviceId to TunnelEndPoint
454 Device srcDevice = deviceService.getDevice(src);
455 Device dstDevice = deviceService.getDevice(dst);
Avantika-Huawei73862d42016-05-12 18:58:06 +0530456
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530457 if (srcDevice == null || dstDevice == null) {
458 // Device is not known.
Satish Kba1c9122017-04-05 15:27:23 +0530459 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo,
460 loadBalancing));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530461 return false;
462 }
463
464 // In future projections instead of annotations will be used to fetch LSR ID.
465 String srcLsrId = srcDevice.annotations().value(LSRID);
466 String dstLsrId = dstDevice.annotations().value(LSRID);
467
468 if (srcLsrId == null || dstLsrId == null) {
469 // LSR id is not known.
Satish Kba1c9122017-04-05 15:27:23 +0530470 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo,
471 loadBalancing));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530472 return false;
473 }
474
Avantika-Huawei032a9872016-05-27 22:57:38 +0530475 // Get device config from netconfig, to ascertain that session with ingress is present.
476 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(srcLsrId), DeviceCapability.class);
477 if (cfg == null) {
478 log.debug("No session to ingress.");
Satish Kba1c9122017-04-05 15:27:23 +0530479 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo,
480 loadBalancing));
Avantika-Huawei032a9872016-05-27 22:57:38 +0530481 return false;
482 }
483
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530484 TunnelEndPoint srcEndPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(srcLsrId));
485 TunnelEndPoint dstEndPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(dstLsrId));
486
487 double bwConstraintValue = 0;
488 CostConstraint costConstraint = null;
489 if (constraints != null) {
490 constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspType.name())));
491 Iterator<Constraint> iterator = constraints.iterator();
492
493 while (iterator.hasNext()) {
494 Constraint constraint = iterator.next();
Satish K2eb5d842017-04-04 16:28:37 +0530495 if (constraint instanceof PceBandwidthConstraint) {
496 bwConstraintValue = ((PceBandwidthConstraint) constraint).bandwidth().bps();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530497 } else if (constraint instanceof CostConstraint) {
498 costConstraint = (CostConstraint) constraint;
499 }
500 }
501
502 /*
503 * Add cost at the end of the list of constraints. The path computation algorithm also computes cumulative
504 * cost. The function which checks the limiting/capability constraints also returns per link cost. This
505 * function can either return the result of limiting/capability constraint validation or the value of link
506 * cost, depending upon what is the last constraint in the loop.
507 */
508 if (costConstraint != null) {
509 constraints.remove(costConstraint);
510 constraints.add(costConstraint);
511 }
512 } else {
513 constraints = new LinkedList<>();
514 constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspType.name())));
515 }
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530516 Set<Path> computedPathSet = Sets.newLinkedHashSet();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530517
Satish Kba1c9122017-04-05 15:27:23 +0530518 if (loadBalancing) {
519 return setupDisjointPaths(src, dst, constraints, tunnelName, bwConstraintValue, lspType, costConstraint,
520 srcEndPoint, dstEndPoint);
521 }
522
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530523 if (explicitPathInfo != null && !explicitPathInfo.isEmpty()) {
524 List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo, src, dst, constraints);
525 if (finalComputedPath == null) {
526 return false;
527 }
528
529 pceStore.tunnelNameExplicitPathInfoMap(tunnelName, explicitPathInfo);
530 List<Link> links = new LinkedList<>();
531 double totalCost = 0;
532 // Add all partial computed paths
533 for (Path path : finalComputedPath) {
534 links.addAll(path.links());
535 totalCost = totalCost + path.cost();
536 }
Ray Milkeya7cf8c82018-02-08 15:07:06 -0800537 computedPathSet.add(new DefaultPath(finalComputedPath.iterator().next().providerId(), links,
538 ScalarWeight.toWeight(totalCost)));
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530539 } else {
540 computedPathSet = computePath(src, dst, constraints);
541 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530542
543 // NO-PATH
544 if (computedPathSet.isEmpty()) {
Satish Kba1c9122017-04-05 15:27:23 +0530545 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo,
546 loadBalancing));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530547 return false;
548 }
549
550 Builder annotationBuilder = DefaultAnnotations.builder();
551 if (bwConstraintValue != 0) {
552 annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue));
553 }
554 if (costConstraint != null) {
555 annotationBuilder.set(COST_TYPE, String.valueOf(costConstraint.type()));
556 }
557 annotationBuilder.set(LSP_SIG_TYPE, lspType.name());
558 annotationBuilder.set(PCE_INIT, TRUE);
559 annotationBuilder.set(DELEGATE, TRUE);
560
561 Path computedPath = computedPathSet.iterator().next();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530562
563 if (lspType != WITH_SIGNALLING) {
564 /*
565 * Local LSP id which is assigned by RSVP for RSVP signalled LSPs, will be assigned by
566 * PCE for non-RSVP signalled LSPs.
567 */
568 annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(getNextLocalLspId()));
569 }
570
571 // For SR-TE tunnels, call SR manager for label stack and put it inside tunnel.
572 Tunnel tunnel = new DefaultTunnel(null, srcEndPoint, dstEndPoint, MPLS, INIT, null, null,
573 TunnelName.tunnelName(tunnelName), computedPath,
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530574 annotationBuilder.build());
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530575
Satish K2eb5d842017-04-04 16:28:37 +0530576 // Allocate bandwidth for all tunnels.
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530577 if (bwConstraintValue != 0) {
Satish K2eb5d842017-04-04 16:28:37 +0530578 if (!reserveBandwidth(computedPath, bwConstraintValue, null)) {
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530579 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints,
Satish Kba1c9122017-04-05 15:27:23 +0530580 lspType, explicitPathInfo, loadBalancing));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530581 return false;
582 }
583 }
584
585 TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath);
586 if (tunnelId == null) {
Satish Kba1c9122017-04-05 15:27:23 +0530587 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo,
588 loadBalancing));
Satish K2eb5d842017-04-04 16:28:37 +0530589
590 if (bwConstraintValue != 0) {
591 computedPath.links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln),
592 Double.parseDouble(tunnel.annotations().value(BANDWIDTH))));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530593 }
Satish K2eb5d842017-04-04 16:28:37 +0530594
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530595 return false;
596 }
597
Satish K2eb5d842017-04-04 16:28:37 +0530598 if (bwConstraintValue != 0 && lspType == WITH_SIGNALLING) {
599 rsvpTunnelsWithLocalBw.add(tunnelId);
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530600 }
Satish K2eb5d842017-04-04 16:28:37 +0530601
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530602 return true;
603 }
Avantika-Huawei73862d42016-05-12 18:58:06 +0530604
Satish Kba1c9122017-04-05 15:27:23 +0530605 private boolean setupDisjointPaths(DeviceId src, DeviceId dst, List<Constraint> constraints, String tunnelName,
606 double bwConstraintValue, LspType lspType, CostConstraint costConstraint,
607 TunnelEndPoint srcEndPoint, TunnelEndPoint dstEndPoint) {
608 Set<DisjointPath> paths = pathService.getDisjointPaths(src, dst, weight(constraints));
609
610 // NO-PATH
611 if (paths.isEmpty()) {
612 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, null, true));
613 return false;
614 }
615
Ray Milkey74e59132018-01-17 15:24:52 -0800616 DisjointPath path = paths.iterator().next();
Satish Kba1c9122017-04-05 15:27:23 +0530617
618 Builder annotationBuilder = DefaultAnnotations.builder();
619 double bw = 0;
620 if (bwConstraintValue != 0) {
621 //TODO: BW needs to be divided by 2 :: bwConstraintValue/2
622 bw = bwConstraintValue / 2;
623 annotationBuilder.set(BANDWIDTH, String.valueOf(bw));
624 }
625 if (costConstraint != null) {
626 annotationBuilder.set(COST_TYPE, String.valueOf(costConstraint.type()));
627 }
628 annotationBuilder.set(LSP_SIG_TYPE, lspType.name());
629 annotationBuilder.set(PCE_INIT, TRUE);
630 annotationBuilder.set(DELEGATE, TRUE);
631 annotationBuilder.set(LOAD_BALANCING_PATH_NAME, tunnelName);
632
633 //Path computedPath = computedPathSet.iterator().next();
634
635 if (lspType != WITH_SIGNALLING) {
636 /*
637 * Local LSP id which is assigned by RSVP for RSVP signalled LSPs, will be assigned by
638 * PCE for non-RSVP signalled LSPs.
639 */
640 annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(getNextLocalLspId()));
641 }
642
643 //Generate different tunnel name for disjoint paths
644 String tunnel1 = (new StringBuilder()).append(tunnelName).append("_1").toString();
645 String tunnel2 = (new StringBuilder()).append(tunnelName).append("_2").toString();
646
647 // For SR-TE tunnels, call SR manager for label stack and put it inside tunnel.
648 Tunnel tunnelPrimary = new DefaultTunnel(null, srcEndPoint, dstEndPoint, MPLS, INIT, null, null,
649 TunnelName.tunnelName(tunnel1), path.primary(),
650 annotationBuilder.build());
651
652 Tunnel tunnelBackup = new DefaultTunnel(null, srcEndPoint, dstEndPoint, MPLS, INIT, null, null,
653 TunnelName.tunnelName(tunnel2), path.backup(),
654 annotationBuilder.build());
655
656 // Allocate bandwidth.
657 if (bwConstraintValue != 0) {
658 if (!reserveBandwidth(path.primary(), bw, null)) {
659 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnel1, constraints,
660 lspType, null, true));
661 return false;
662 }
663
664 if (!reserveBandwidth(path.backup(), bw, null)) {
665 //Release bandwidth resource for tunnel1
666 if (bwConstraintValue != 0) {
667 path.primary().links().forEach(ln ->
668 bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln),
669 Double.parseDouble(tunnelPrimary.annotations().value(BANDWIDTH))));
670 }
671
672 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnel2, constraints,
673 lspType, null, true));
674 return false;
675 }
676 }
677
678 TunnelId tunnelId1 = tunnelService.setupTunnel(appId, src, tunnelPrimary, path.primary());
679 if (tunnelId1 == null) {
680 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, null, true));
681
682 if (bwConstraintValue != 0) {
683 path.primary().links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln),
684 Double.parseDouble(tunnelPrimary.annotations().value(BANDWIDTH))));
685 }
686
687 return false;
688 }
689
690 TunnelId tunnelId2 = tunnelService.setupTunnel(appId, src, tunnelBackup, path.backup());
691 if (tunnelId2 == null) {
692 //Release 1st tunnel
rohitsharan483bed42017-04-12 19:04:57 +0530693 releasePath(tunnelId1);
Satish Kba1c9122017-04-05 15:27:23 +0530694
695 pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, null, true));
696
697 if (bwConstraintValue != 0) {
698 path.backup().links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln),
699 Double.parseDouble(tunnelBackup.annotations().value(BANDWIDTH))));
700 }
701
702 return false;
703 }
704
705 pceStore.addLoadBalancingTunnelIdsInfo(tunnelName, tunnelId1, tunnelId2);
706 //pceStore.addDisjointPathInfo(tunnelName, path);
707 return true;
708 }
709
Avantika-Huawei73862d42016-05-12 18:58:06 +0530710 @Override
711 public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) {
712 checkNotNull(tunnelId);
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530713 Set<Path> computedPathSet = Sets.newLinkedHashSet();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530714 Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
Avantika-Huawei73862d42016-05-12 18:58:06 +0530715
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530716 if (tunnel == null) {
717 return false;
718 }
Avantika-Huawei73862d42016-05-12 18:58:06 +0530719
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530720 if (tunnel.type() != MPLS || FALSE.equalsIgnoreCase(tunnel.annotations().value(DELEGATE))) {
721 // Only delegated LSPs can be updated.
722 return false;
723 }
724
725 List<Link> links = tunnel.path().links();
726 String lspSigType = tunnel.annotations().value(LSP_SIG_TYPE);
727 double bwConstraintValue = 0;
Priyanka B3f92c5a2016-05-27 10:14:16 +0530728 String costType = null;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530729 SharedBandwidthConstraint shBwConstraint = null;
Satish K2eb5d842017-04-04 16:28:37 +0530730 PceBandwidthConstraint bwConstraint = null;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530731 CostConstraint costConstraint = null;
732
733 if (constraints != null) {
734 // Call path computation in shared bandwidth mode.
735 Iterator<Constraint> iterator = constraints.iterator();
736 while (iterator.hasNext()) {
737 Constraint constraint = iterator.next();
Satish K2eb5d842017-04-04 16:28:37 +0530738 if (constraint instanceof PceBandwidthConstraint) {
739 bwConstraint = (PceBandwidthConstraint) constraint;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530740 bwConstraintValue = bwConstraint.bandwidth().bps();
741 } else if (constraint instanceof CostConstraint) {
742 costConstraint = (CostConstraint) constraint;
Avantika-Huawei032a9872016-05-27 22:57:38 +0530743 costType = costConstraint.type().name();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530744 }
745 }
746
747 // Remove and keep the cost constraint at the end of the list of constraints.
748 if (costConstraint != null) {
749 constraints.remove(costConstraint);
750 }
751
752 Bandwidth existingBwValue = null;
753 String existingBwAnnotation = tunnel.annotations().value(BANDWIDTH);
754 if (existingBwAnnotation != null) {
755 existingBwValue = Bandwidth.bps(Double.parseDouble(existingBwAnnotation));
756
757 /*
758 * The computation is a shared bandwidth constraint based, so need to remove bandwidth constraint which
759 * has been utilized to create shared bandwidth constraint.
760 */
761 if (bwConstraint != null) {
762 constraints.remove(bwConstraint);
763 }
764 }
765
766 if (existingBwValue != null) {
Priyanka B3fdb9dd2016-08-08 10:47:24 +0530767 if (bwConstraint == null) {
Priyanka B4c3cef02016-06-14 20:27:53 +0530768 bwConstraintValue = existingBwValue.bps();
769 }
770 //If bandwidth constraints not specified , take existing bandwidth for shared bandwidth calculation
771 shBwConstraint = bwConstraint != null ? new SharedBandwidthConstraint(links,
772 existingBwValue, bwConstraint.bandwidth()) : new SharedBandwidthConstraint(links,
773 existingBwValue, existingBwValue);
774
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530775 constraints.add(shBwConstraint);
776 }
777 } else {
778 constraints = new LinkedList<>();
779 }
780
781 constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspSigType)));
782 if (costConstraint != null) {
783 constraints.add(costConstraint);
Priyanka B3fdb9dd2016-08-08 10:47:24 +0530784 } else {
785 //Take cost constraint from old tunnel if it is not specified in update flow
786 costType = tunnel.annotations().value(COST_TYPE);
787 costConstraint = CostConstraint.of(CostConstraint.Type.valueOf(costType));
788 constraints.add(costConstraint);
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530789 }
790
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530791 List<ExplicitPathInfo> explicitPathInfo = pceStore
792 .getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value());
793 if (explicitPathInfo != null) {
794 List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo,
795 tunnel.path().src().deviceId(), tunnel.path().dst().deviceId(),
796 constraints);
797
798 if (finalComputedPath == null) {
799 return false;
800 }
801
802 List<Link> totalLinks = new LinkedList<>();
803 double totalCost = 0;
804 //Add all partial computed paths
805 for (Path path : finalComputedPath) {
806 totalLinks.addAll(path.links());
807 totalCost = totalCost + path.cost();
808 }
809 computedPathSet.add(new DefaultPath(finalComputedPath.iterator().next().providerId(),
Ray Milkeya7cf8c82018-02-08 15:07:06 -0800810 totalLinks, ScalarWeight.toWeight(totalCost)));
Priyanka Bbae0eeb12016-11-30 11:59:48 +0530811 } else {
812 computedPathSet = computePath(tunnel.path().src().deviceId(), tunnel.path().dst().deviceId(),
813 constraints);
814 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530815
816 // NO-PATH
817 if (computedPathSet.isEmpty()) {
818 return false;
819 }
820
821 Builder annotationBuilder = DefaultAnnotations.builder();
822 annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue));
Priyanka B3f92c5a2016-05-27 10:14:16 +0530823 if (costType != null) {
824 annotationBuilder.set(COST_TYPE, costType);
825 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530826 annotationBuilder.set(LSP_SIG_TYPE, lspSigType);
827 annotationBuilder.set(PCE_INIT, TRUE);
828 annotationBuilder.set(DELEGATE, TRUE);
829 annotationBuilder.set(PLSP_ID, tunnel.annotations().value(PLSP_ID));
830 annotationBuilder.set(PCC_TUNNEL_ID, tunnel.annotations().value(PCC_TUNNEL_ID));
831
832 Path computedPath = computedPathSet.iterator().next();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530833 LspType lspType = LspType.valueOf(lspSigType);
834 long localLspId = 0;
835 if (lspType != WITH_SIGNALLING) {
836 /*
837 * Local LSP id which is assigned by RSVP for RSVP signalled LSPs, will be assigned by
838 * PCE for non-RSVP signalled LSPs.
839 */
840 localLspId = getNextLocalLspId();
841 annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(localLspId));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530842 }
843
844 Tunnel updatedTunnel = new DefaultTunnel(null, tunnel.src(), tunnel.dst(), MPLS, INIT, null, null,
845 tunnel.tunnelName(), computedPath,
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530846 annotationBuilder.build());
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530847
Satish K2eb5d842017-04-04 16:28:37 +0530848 // Allocate shared bandwidth for all tunnels.
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530849 if (bwConstraintValue != 0) {
Satish K2eb5d842017-04-04 16:28:37 +0530850 if (!reserveBandwidth(computedPath, bwConstraintValue, shBwConstraint)) {
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530851 return false;
852 }
853 }
854
855 TunnelId updatedTunnelId = tunnelService.setupTunnel(appId, links.get(0).src().deviceId(), updatedTunnel,
856 computedPath);
857
858 if (updatedTunnelId == null) {
Satish K2eb5d842017-04-04 16:28:37 +0530859 if (bwConstraintValue != 0) {
860 releaseSharedBwForNewTunnel(computedPath, bwConstraintValue, shBwConstraint);
Avantika-Huaweidbdf7722016-05-21 14:20:31 +0530861 }
862 return false;
863 }
864
Satish K2eb5d842017-04-04 16:28:37 +0530865 if (bwConstraintValue != 0 && lspType == WITH_SIGNALLING) {
866 rsvpTunnelsWithLocalBw.add(updatedTunnelId);
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530867 }
868
Avantika-Huawei73862d42016-05-12 18:58:06 +0530869 return true;
870 }
871
872 @Override
873 public boolean releasePath(TunnelId tunnelId) {
874 checkNotNull(tunnelId);
875 // 1. Query Tunnel from Tunnel manager.
876 Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
877
878 if (tunnel == null) {
879 return false;
880 }
881
882 // 2. Call tunnel service.
883 return tunnelService.downTunnel(appId, tunnel.tunnelId());
884 }
885
886 @Override
Satish Kba1c9122017-04-05 15:27:23 +0530887 public boolean releasePath(String loadBalancingPathName) {
888 checkNotNull(loadBalancingPathName);
889
890 List<TunnelId> tunnelIds = pceStore.getLoadBalancingTunnelIds(loadBalancingPathName);
891 if (tunnelIds != null && !tunnelIds.isEmpty()) {
892 for (TunnelId id : tunnelIds) {
893 if (!tunnelService.downTunnel(appId, id)) {
894 return false;
895 }
896 }
897
898 //pceStore.removeDisjointPathInfo(loadBalancedPathName);
899 pceStore.removeLoadBalancingTunnelIdsInfo(loadBalancingPathName);
900 return true;
901 }
902
903 return false;
904 }
905
906 @Override
Avantika-Huawei73862d42016-05-12 18:58:06 +0530907 public Iterable<Tunnel> queryAllPath() {
908 return tunnelService.queryTunnel(MPLS);
909 }
910
911 @Override
912 public Tunnel queryPath(TunnelId tunnelId) {
913 return tunnelService.queryTunnel(tunnelId);
914 }
915
Satish K2eb5d842017-04-04 16:28:37 +0530916 private boolean releaseSharedBwForNewTunnel(Path computedPath, double bandwidthConstraint,
917 SharedBandwidthConstraint shBwConstraint) {
918 checkNotNull(computedPath);
Satish K2eb5d842017-04-04 16:28:37 +0530919 double bwToAllocate;
920
921 Double additionalBwValue = null;
922 if (shBwConstraint != null) {
923 additionalBwValue = ((bandwidthConstraint - shBwConstraint.sharedBwValue().bps()) <= 0) ? null
924 : (bandwidthConstraint - shBwConstraint.sharedBwValue().bps());
925 }
926
927 for (Link link : computedPath.links()) {
928 bwToAllocate = 0;
929 if ((shBwConstraint != null) && (shBwConstraint.links().contains(link))) {
930 if (additionalBwValue != null) {
931 bwToAllocate = additionalBwValue;
932 }
933 } else {
934 bwToAllocate = bandwidthConstraint;
935 }
936
937 if (bwToAllocate != 0) {
938 bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(link), bwToAllocate);
939 }
940 }
941 return true;
942 }
943
Avantika-Huawei73862d42016-05-12 18:58:06 +0530944 /**
945 * Returns the next local LSP identifier to be used either by getting from
946 * freed list if available otherwise generating a new one.
947 *
948 * @return value of local LSP identifier
949 */
Priyanka B4c3b4512016-07-22 11:41:49 +0530950 private synchronized short getNextLocalLspId() {
Avantika-Huawei73862d42016-05-12 18:58:06 +0530951 // If there is any free id use it. Otherwise generate new id.
952 if (localLspIdFreeList.isEmpty()) {
953 return (short) localLspIdIdGen.getNewId();
954 }
955 Iterator<Short> it = localLspIdFreeList.iterator();
956 Short value = it.next();
957 localLspIdFreeList.remove(value);
958 return value;
959 }
960
Ray Milkey7483e1b2018-02-07 15:43:01 -0800961 protected class TeConstraintBasedLinkWeight implements LinkWeigher {
Priyanka Bb6963582016-05-20 20:21:20 +0530962
963 private final List<Constraint> constraints;
964
965 /**
966 * Creates a new edge-weight function capable of evaluating links
967 * on the basis of the specified constraints.
968 *
969 * @param constraints path constraints
970 */
971 public TeConstraintBasedLinkWeight(List<Constraint> constraints) {
972 if (constraints == null) {
973 this.constraints = Collections.emptyList();
974 } else {
975 this.constraints = ImmutableList.copyOf(constraints);
976 }
977 }
978
979 @Override
Ray Milkey7483e1b2018-02-07 15:43:01 -0800980 public Weight getInitialWeight() {
981 return ScalarWeight.toWeight(0.0);
982 }
983
984 @Override
985 public Weight getNonViableWeight() {
986 return ScalarWeight.toWeight(0.0);
987 }
988
989 @Override
990 public Weight weight(TopologyEdge edge) {
Priyanka Bb6963582016-05-20 20:21:20 +0530991 if (!constraints.iterator().hasNext()) {
992 //Takes default cost/hopcount as 1 if no constraints specified
Ray Milkey7483e1b2018-02-07 15:43:01 -0800993 return ScalarWeight.toWeight(1.0);
Priyanka Bb6963582016-05-20 20:21:20 +0530994 }
995
996 Iterator<Constraint> it = constraints.iterator();
997 double cost = 1;
998
999 //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
1000 while (it.hasNext() && cost > 0) {
1001 Constraint constraint = it.next();
1002 if (constraint instanceof CapabilityConstraint) {
Avantika-Huawei032a9872016-05-27 22:57:38 +05301003 cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService,
1004 netCfgService) ? 1 : -1;
Satish K2eb5d842017-04-04 16:28:37 +05301005 } else if (constraint instanceof PceBandwidthConstraint) {
1006 cost = ((PceBandwidthConstraint) constraint).isValidLink(edge.link(),
1007 bandwidthMgmtService) ? 1 : -1;
1008 } else if (constraint instanceof SharedBandwidthConstraint) {
1009 cost = ((SharedBandwidthConstraint) constraint).isValidLink(edge.link(),
1010 bandwidthMgmtService) ? 1 : -1;
1011 } else if (constraint instanceof CostConstraint) {
1012 cost = ((CostConstraint) constraint).isValidLink(edge.link(), netCfgService);
Priyanka Bb6963582016-05-20 20:21:20 +05301013 } else {
Satish K2eb5d842017-04-04 16:28:37 +05301014 cost = constraint.cost(edge.link(), null);
Priyanka Bb6963582016-05-20 20:21:20 +05301015 }
1016 }
Ray Milkey7483e1b2018-02-07 15:43:01 -08001017 return ScalarWeight.toWeight(cost);
Priyanka Bb6963582016-05-20 20:21:20 +05301018 }
1019 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301020
Priyanka B3f92c5a2016-05-27 10:14:16 +05301021 //TODO: annotations used for temporarily later projection/network config will be used
1022 private class InternalTopologyListener implements TopologyListener {
1023 @Override
1024 public void event(TopologyEvent event) {
1025 event.reasons().forEach(e -> {
1026 //If event type is link removed, get the impacted tunnel
1027 if (e instanceof LinkEvent) {
1028 LinkEvent linkEvent = (LinkEvent) e;
1029 if (linkEvent.type() == LinkEvent.Type.LINK_REMOVED) {
1030 tunnelService.queryTunnel(MPLS).forEach(t -> {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301031 if (t.path().links().contains((e.subject()))) {
Priyanka B3f92c5a2016-05-27 10:14:16 +05301032 // Check whether this ONOS instance is master for ingress device if yes,
1033 // recompute and send update
1034 checkForMasterAndUpdateTunnel(t.path().src().deviceId(), t);
1035 }
1036 });
1037 }
1038 }
1039 });
1040 }
1041 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301042
Priyanka B3f92c5a2016-05-27 10:14:16 +05301043 private boolean checkForMasterAndUpdateTunnel(DeviceId src, Tunnel tunnel) {
1044 /**
1045 * Master of ingress node will recompute and also delegation flag must be set.
1046 */
1047 if (mastershipService.isLocalMaster(src)
1048 && Boolean.valueOf(tunnel.annotations().value(DELEGATE)) != null) {
1049 LinkedList<Constraint> constraintList = new LinkedList<>();
1050
1051 if (tunnel.annotations().value(BANDWIDTH) != null) {
1052 //Requested bandwidth will be same as previous allocated bandwidth for the tunnel
Satish K2eb5d842017-04-04 16:28:37 +05301053 PceBandwidthConstraint localConst = new PceBandwidthConstraint(Bandwidth.bps(Double.parseDouble(tunnel
Priyanka B3f92c5a2016-05-27 10:14:16 +05301054 .annotations().value(BANDWIDTH))));
1055 constraintList.add(localConst);
1056 }
1057 if (tunnel.annotations().value(COST_TYPE) != null) {
1058 constraintList.add(CostConstraint.of(CostConstraint.Type.valueOf(tunnel.annotations().value(
1059 COST_TYPE))));
1060 }
Priyanka B9fa4ed32016-05-27 11:59:24 +05301061
1062 /*
1063 * If tunnel was UP after recomputation failed then store failed path in PCE store send PCIntiate(remove)
1064 * and If tunnel is failed and computation fails nothing to do because tunnel status will be same[Failed]
1065 */
1066 if (!updatePath(tunnel.tunnelId(), constraintList) && !tunnel.state().equals(Tunnel.State.FAILED)) {
Priyanka B3f92c5a2016-05-27 10:14:16 +05301067 // If updation fails store in PCE store as failed path
1068 // then PCInitiate (Remove)
1069 pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel
1070 .path().dst().deviceId(), tunnel.tunnelName().value(), constraintList,
Priyanka Bbae0eeb12016-11-30 11:59:48 +05301071 LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)),
Satish Kba1c9122017-04-05 15:27:23 +05301072 pceStore.getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value()),
1073 tunnel.annotations().value(LOAD_BALANCING_PATH_NAME) != null ? true : false));
Priyanka B3f92c5a2016-05-27 10:14:16 +05301074 //Release that tunnel calling PCInitiate
1075 releasePath(tunnel.tunnelId());
1076 }
1077 }
1078
1079 return false;
1080 }
1081
1082 // Allocates the bandwidth locally for PCECC tunnels.
Satish K2eb5d842017-04-04 16:28:37 +05301083 private boolean reserveBandwidth(Path computedPath, double bandwidthConstraint,
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301084 SharedBandwidthConstraint shBwConstraint) {
1085 checkNotNull(computedPath);
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301086 Resource resource = null;
1087 double bwToAllocate = 0;
Satish K2eb5d842017-04-04 16:28:37 +05301088 Map<Link, Double> linkMap = new HashMap<>();
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301089
1090 /**
1091 * Shared bandwidth sub-case : Lesser bandwidth required than original -
1092 * No reservation required.
1093 */
1094 Double additionalBwValue = null;
1095 if (shBwConstraint != null) {
1096 additionalBwValue = ((bandwidthConstraint - shBwConstraint.sharedBwValue().bps()) <= 0) ? null
1097 : (bandwidthConstraint - shBwConstraint.sharedBwValue().bps());
1098 }
1099
1100 Optional<ResourceAllocation> resAlloc = null;
1101 for (Link link : computedPath.links()) {
1102 bwToAllocate = 0;
1103 if ((shBwConstraint != null) && (shBwConstraint.links().contains(link))) {
1104 if (additionalBwValue != null) {
Priyanka B4c3b4512016-07-22 11:41:49 +05301105 bwToAllocate = additionalBwValue;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301106 }
1107 } else {
1108 bwToAllocate = bandwidthConstraint;
1109 }
1110
1111 /**
1112 * In shared bandwidth cases, where new BW is lesser than old BW, it
1113 * is not required to allocate anything.
1114 */
1115 if (bwToAllocate != 0) {
Satish K2eb5d842017-04-04 16:28:37 +05301116 if (!bandwidthMgmtService.allocLocalReservedBw(LinkKey.linkKey(link.src(), link.dst()),
1117 bwToAllocate)) {
1118 // If allocation for any link fails, then release the partially allocated bandwidth
1119 // for all links allocated
1120 linkMap.forEach((ln, aDouble) -> bandwidthMgmtService
1121 .releaseLocalReservedBw(LinkKey.linkKey(ln), aDouble));
1122 return false;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301123 }
Satish K2eb5d842017-04-04 16:28:37 +05301124
1125 linkMap.put(link, bwToAllocate);
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301126 }
1127 }
1128
Satish K2eb5d842017-04-04 16:28:37 +05301129 return true;
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301130 }
1131
1132 /*
1133 * Deallocates the bandwidth which is reserved locally for PCECC tunnels.
1134 */
1135 private void releaseBandwidth(Tunnel tunnel) {
1136 // Between same source and destination, search the tunnel with same symbolic path name.
1137 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnel.src(), tunnel.dst());
1138 Tunnel newTunnel = null;
1139 for (Tunnel tunnelObj : tunnelQueryResult) {
1140 if (tunnel.tunnelName().value().equals(tunnelObj.tunnelName().value())) {
1141 newTunnel = tunnelObj;
1142 break;
1143 }
1144 }
1145
1146 // Even if one link is shared, the bandwidth release should happen based on shared mechanism.
1147 boolean isLinkShared = false;
1148 if (newTunnel != null) {
1149 for (Link link : tunnel.path().links()) {
1150 if (newTunnel.path().links().contains(link)) {
1151 isLinkShared = true;
1152 break;
1153 }
1154 }
1155 }
1156
1157 if (isLinkShared) {
1158 releaseSharedBandwidth(newTunnel, tunnel);
1159 return;
1160 }
1161
Satish K2eb5d842017-04-04 16:28:37 +05301162 tunnel.path().links().forEach(tn -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(tn),
1163 Double.parseDouble(tunnel.annotations().value(BANDWIDTH))));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301164 }
1165
1166 /**
1167 * Re-allocates the bandwidth for the tunnel for which the bandwidth was
1168 * allocated in shared mode initially.
1169 */
1170 private synchronized void releaseSharedBandwidth(Tunnel newTunnel, Tunnel oldTunnel) {
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301171
Satish K2eb5d842017-04-04 16:28:37 +05301172 boolean isAllocate = false;
1173 Double oldTunnelBw = Double.parseDouble(oldTunnel.annotations().value(BANDWIDTH));
1174 Double newTunnelBw = Double.parseDouble(newTunnel.annotations().value(BANDWIDTH));
1175
1176 if (newTunnelBw > oldTunnelBw) {
1177 isAllocate = true;
Priyanka B4c3b4512016-07-22 11:41:49 +05301178 }
1179
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301180 for (Link link : newTunnel.path().links()) {
Satish K2eb5d842017-04-04 16:28:37 +05301181 if (oldTunnel.path().links().contains(link)) {
1182 if (!isAllocate) {
1183 bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(link),
1184 oldTunnelBw - newTunnelBw);
1185 }
1186 } else {
1187 bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(link), oldTunnelBw);
1188 }
Mahesh Poojary Huawei1d17cad2016-06-02 12:53:41 +05301189 }
1190 }
1191
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301192 // Listens on tunnel events.
1193 private class InnerTunnelListener implements TunnelListener {
1194 @Override
1195 public void event(TunnelEvent event) {
1196 // Event gets generated with old tunnel object.
1197 Tunnel tunnel = event.subject();
1198 if (tunnel.type() != MPLS) {
1199 return;
1200 }
1201
1202 LspType lspType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
1203 String tunnelBandwidth = tunnel.annotations().value(BANDWIDTH);
1204 double bwConstraintValue = 0;
1205 if (tunnelBandwidth != null) {
1206 bwConstraintValue = Double.parseDouble(tunnelBandwidth);
1207 }
1208
1209 switch (event.type()) {
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301210 case TUNNEL_UPDATED:
Satish K2eb5d842017-04-04 16:28:37 +05301211 if (rsvpTunnelsWithLocalBw.contains(tunnel.tunnelId())) {
1212 releaseBandwidth(event.subject());
1213 rsvpTunnelsWithLocalBw.remove(tunnel.tunnelId());
1214 }
1215
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301216 if (tunnel.state() == UNSTABLE) {
1217 /*
1218 * During LSP DB sync if PCC doesn't report LSP which was PCE initiated, it's state is turned into
1219 * unstable so that it can be setup again. Add into failed path store so that it can be recomputed
1220 * and setup while global reoptimization.
1221 */
1222
1223 List<Constraint> constraints = new LinkedList<>();
1224 String bandwidth = tunnel.annotations().value(BANDWIDTH);
1225 if (bandwidth != null) {
Satish K2eb5d842017-04-04 16:28:37 +05301226 constraints.add(new PceBandwidthConstraint(Bandwidth
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301227 .bps(Double.parseDouble(bandwidth))));
1228 }
1229
1230 String costType = tunnel.annotations().value(COST_TYPE);
1231 if (costType != null) {
1232 CostConstraint costConstraint = new CostConstraint(CostConstraint.Type.valueOf(costType));
1233 constraints.add(costConstraint);
1234 }
1235
1236 constraints.add(CapabilityConstraint
1237 .of(CapabilityType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))));
1238
1239 List<Link> links = tunnel.path().links();
1240 pceStore.addFailedPathInfo(new PcePathInfo(links.get(0).src().deviceId(),
1241 links.get(links.size() - 1).dst().deviceId(),
Priyanka Bbae0eeb12016-11-30 11:59:48 +05301242 tunnel.tunnelName().value(), constraints, lspType,
1243 pceStore.getTunnelNameExplicitPathInfoMap(tunnel
Satish Kba1c9122017-04-05 15:27:23 +05301244 .tunnelName().value()), tunnel.annotations()
1245 .value(LOAD_BALANCING_PATH_NAME) != null ? true : false));
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301246 }
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +05301247
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301248 break;
1249
1250 case TUNNEL_REMOVED:
1251 if (lspType != WITH_SIGNALLING) {
1252 localLspIdFreeList.add(Short.valueOf(tunnel.annotations().value(LOCAL_LSP_ID)));
1253 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301254 // If not zero bandwidth, and delegated (initiated LSPs will also be delegated).
Satish K2eb5d842017-04-04 16:28:37 +05301255 if (bwConstraintValue != 0 && mastershipService.getLocalRole(tunnel.path().src()
1256 .deviceId()) == MastershipRole.MASTER) {
1257 if (lspType != WITH_SIGNALLING) {
1258 releaseBandwidth(tunnel);
1259 }
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301260 }
Priyanka B4c3b4512016-07-22 11:41:49 +05301261
Satish K2eb5d842017-04-04 16:28:37 +05301262 /*if (pceStore.getTunnelInfo(tunnel.tunnelId()) != null) {
Priyanka B4c3b4512016-07-22 11:41:49 +05301263 pceStore.removeTunnelInfo(tunnel.tunnelId());
Satish K2eb5d842017-04-04 16:28:37 +05301264 }*/
Priyanka B4c3b4512016-07-22 11:41:49 +05301265
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301266 break;
1267
1268 default:
1269 break;
1270
1271 }
1272 return;
1273 }
1274 }
1275
Priyanka Bbae0eeb12016-11-30 11:59:48 +05301276 @Override
1277 public List<ExplicitPathInfo> explicitPathInfoList(String tunnelName) {
1278 return pceStore.getTunnelNameExplicitPathInfoMap(tunnelName);
1279 }
1280
Satish Kba1c9122017-04-05 15:27:23 +05301281 @Override
1282 public List<TunnelId> queryLoadBalancingPath(String pathName) {
1283 return pceStore.getLoadBalancingTunnelIds(pathName);
1284 }
1285
Priyanka B9fa4ed32016-05-27 11:59:24 +05301286 //Computes path from tunnel store and also path failed to setup.
1287 private void callForOptimization() {
1288 //Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)]
1289 for (PcePathInfo failedPathInfo : pceStore.getFailedPathInfos()) {
1290 checkForMasterAndSetupPath(failedPathInfo);
1291 }
1292
1293 //Recompute the LSPs for which it was delegated [LSPs stored in tunnel store]
1294 tunnelService.queryTunnel(MPLS).forEach(t -> {
1295 checkForMasterAndUpdateTunnel(t.path().src().deviceId(), t);
1296 });
1297 }
1298
1299 private boolean checkForMasterAndSetupPath(PcePathInfo failedPathInfo) {
1300 /**
1301 * Master of ingress node will setup the path failed stored in PCE store.
1302 */
1303 if (mastershipService.isLocalMaster(failedPathInfo.src())) {
1304 if (setupPath(failedPathInfo.src(), failedPathInfo.dst(), failedPathInfo.name(),
Priyanka Bbae0eeb12016-11-30 11:59:48 +05301305 failedPathInfo.constraints(), failedPathInfo.lspType(), failedPathInfo.explicitPathInfo())) {
Priyanka B9fa4ed32016-05-27 11:59:24 +05301306 // If computation is success remove that path
1307 pceStore.removeFailedPathInfo(failedPathInfo);
1308 return true;
1309 }
1310 }
1311
1312 return false;
1313 }
1314
1315 //Timer to call global optimization
1316 private class GlobalOptimizationTimer implements Runnable {
1317
1318 public GlobalOptimizationTimer() {
1319 }
1320
1321 @Override
1322 public void run() {
1323 callForOptimization();
1324 }
1325 }
rohitsharan483bed42017-04-12 19:04:57 +05301326}