2 * Copyright (c) 2021 Orange. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.bgpcep.pcep.server.provider;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static com.google.common.base.Preconditions.checkState;
12 import static java.util.Objects.requireNonNull;
14 import com.google.common.util.concurrent.FutureCallback;
15 import java.util.Collection;
16 import java.util.HashMap;
18 import javax.annotation.PreDestroy;
19 import org.opendaylight.graph.ConnectedEdge;
20 import org.opendaylight.graph.ConnectedEdgeTrigger;
21 import org.opendaylight.graph.ConnectedGraph;
22 import org.opendaylight.graph.ConnectedGraphTrigger;
23 import org.opendaylight.graph.ConnectedVertex;
24 import org.opendaylight.graph.ConnectedVertexTrigger;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.binding.api.RpcService;
27 import org.opendaylight.mdsal.binding.api.TransactionChain;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev220720.Edge;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev220720.Vertex;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathStatus;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathType;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PcepNodeConfig;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLsp;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPath;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPathBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.intended.path.ConstraintsBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev220730.AddLsp;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev220730.RemoveLsp;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev220730.UpdateLsp;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
49 import org.opendaylight.yangtools.yang.common.Empty;
50 import org.osgi.service.component.annotations.Deactivate;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
55 * This Class implements the Path Manager in charge of Managed TE Node and Managed TE Path.
57 * @author Olivier Dugeon
60 public final class PathManagerProvider implements FutureCallback<Empty>, AutoCloseable, ConnectedGraphTrigger {
61 private static final Logger LOG = LoggerFactory.getLogger(PathManagerProvider.class);
62 private final InstanceIdentifier<Topology> pcepTopology;
63 private final DataBroker dataBroker;
64 private final DefaultPceServerProvider pceServerProvider;
65 private final AddLsp addLsp;
66 private final UpdateLsp updateLsp;
67 private final RemoveLsp removeLsp;
68 private TransactionChain chain = null;
69 private ConnectedGraph tedGraph = null;
71 private final Map<NodeId, ManagedTeNode> mngNodes = new HashMap<>();
73 public PathManagerProvider(final DataBroker dataBroker,
74 final KeyedInstanceIdentifier<Topology, TopologyKey> topology, final RpcService rpcService,
75 final DefaultPceServerProvider pceServerProvider) {
76 this.dataBroker = requireNonNull(dataBroker);
77 this.pceServerProvider = requireNonNull(pceServerProvider);
78 addLsp = rpcService.getRpc(AddLsp.class);
79 updateLsp = rpcService.getRpc(UpdateLsp.class);
80 removeLsp = rpcService.getRpc(RemoveLsp.class);
81 pcepTopology = requireNonNull(topology);
82 initTransactionChain();
83 tedGraph = getGraph();
84 LOG.info("Path Manager Server started for topology {}", topology.getKey().getTopologyId().getValue());
88 * Remove the Path Manager Server and destroy the transaction chain.
94 tedGraph = pceServerProvider.getTedGraph();
95 if (tedGraph != null) {
96 tedGraph.unRegisterTrigger(this, InstanceIdentifier.keyOf(pcepTopology));
98 destroyTransactionChain();
101 private ConnectedGraph getGraph() {
102 if (tedGraph == null) {
103 tedGraph = pceServerProvider.getTedGraph();
104 if (tedGraph != null) {
105 tedGraph.registerTrigger(this, InstanceIdentifier.keyOf(pcepTopology));
112 * Reset a transaction chain by closing the current chain and starting a new one.
114 private synchronized void initTransactionChain() {
115 LOG.debug("Initializing transaction chain for Path Manager Server {}", this);
116 checkState(chain == null, "Transaction chain has to be closed before being initialized");
117 chain = dataBroker.createMergingTransactionChain();
118 chain.addCallback(this);
122 * Destroy the current transaction chain.
124 private synchronized void destroyTransactionChain() {
126 LOG.debug("Destroy transaction chain for Path Manager {}", this);
132 * Reset the transaction chain only so that the PingPong transaction chain
133 * will become usable again. However, there will be data loss if we do not
134 * apply the previous failed transaction again
136 protected synchronized void resetTransactionChain() {
137 LOG.debug("Resetting transaction chain for Path Manager");
138 destroyTransactionChain();
139 initTransactionChain();
143 public synchronized void onFailure(final Throwable cause) {
144 LOG.error("Path Manager Provider for {}", pcepTopology, cause);
148 public void onSuccess(final Empty value) {
149 LOG.info("Path Manager Provider for {} shut down", pcepTopology);
153 * Setup Managed TE Path to existing Managed Node.
155 * @param teNode Managed TE Node where the TE Path will be enforced
156 * @param lsp TE Path to be inserted in the Managed Node
158 * @return Newly created Managed TE Path
160 private ManagedTePath addManagedTePath(final ManagedTeNode teNode, final ConfiguredLsp lsp) {
161 checkArgument(teNode != null, "Provided Managed TE Node is a null object");
162 checkArgument(lsp != null, "Provided TE Path is a null object");
164 LOG.info("Setup TE Path {} for Node {}", lsp.getName(), teNode.getId());
166 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
167 /* Create Corresponding Managed LSP */
168 final ManagedTePath mngLsp =
171 /* Complete the LSP with the Computed Route */
172 new ConfiguredLspBuilder(lsp)
173 .setPathStatus(PathStatus.Configured)
176 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
177 : pci.computeTePath(lsp.getIntendedPath()))
180 .setType(PathType.Initiated);
182 /* Store this new Managed TE Node */
183 teNode.addManagedTePath(mngLsp);
185 /* Then, setup Path on PCC if it is synchronized */
186 if (teNode.isSync()) {
187 mngLsp.addPath(addLsp);
190 LOG.debug("Added new Managed LSP: {}", mngLsp);
195 * Update TE Path to existing Managed Node.
197 * @param mngPath Managed TE Path to be updated
198 * @param tePath New TE Path to be updated in the Managed Node
200 private ConfiguredLsp updateManagedTePath(final ManagedTePath mngPath, final ConfiguredLsp tePath) {
201 checkArgument(mngPath != null, "Provided Managed TE Path is a null object");
202 checkArgument(tePath != null, "Provided TE Path is a null object");
204 final ManagedTeNode teNode = mngPath.getManagedTeNode();
205 final IntendedPath iPath = tePath.getIntendedPath();
206 final IntendedPath oPath = mngPath.getLsp().getIntendedPath();
207 IntendedPathBuilder ipb = new IntendedPathBuilder(iPath);
209 LOG.info("Update TE Path {} for Node {}", mngPath.getLsp().getName(), teNode.getId());
211 /* Check that Source and Destination have not been modified and revert to old value instead */
212 if (!iPath.getSource().equals(oPath.getSource())) {
213 LOG.warn("Source IP Address {}/{} of TE Path has been modified. Revert to initial one",
214 iPath.getSource(), oPath.getSource());
215 ipb.setSource(oPath.getSource());
217 if (!iPath.getDestination().equals(oPath.getDestination())) {
218 LOG.warn("Destination IP Address {}/{} of TE Path has been modified. Revert to initial one",
219 iPath.getDestination(), oPath.getDestination());
220 ipb.setDestination(oPath.getDestination());
223 /* Same for Address Family i.e. refused to change a TE Path from RSVP-TE to Segment Routing and vice versa */
224 if (!iPath.getConstraints().getAddressFamily().equals(oPath.getConstraints().getAddressFamily())) {
225 LOG.warn("Address Family {}/{} of TE Path has been modified. Revert to initial one",
226 iPath.getConstraints().getAddressFamily(), oPath.getConstraints().getAddressFamily());
227 ipb.setConstraints(new ConstraintsBuilder(iPath.getConstraints())
228 .setAddressFamily(oPath.getConstraints().getAddressFamily()).build());
231 /* Create updated TE Path */
232 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
233 mngPath.setConfiguredLsp(
234 new ConfiguredLspBuilder(tePath)
235 .setIntendedPath(ipb.build())
236 .setPathStatus(PathStatus.Updated)
237 /* Complete it with the new Computed Route */
240 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
241 : pci.computeTePath(tePath.getIntendedPath()))
244 /* Finally, update the new TE Path for this Node ID */
245 mngPath.updateToDataStore();
247 /* Finally, update Path on PCC if it is synchronized and we computed a valid path */
248 if (teNode.isSync()) {
249 mngPath.updatePath(updateLsp);
252 LOG.debug("Updated Managed Paths: {}", mngPath);
253 return mngPath.getLsp();
258 * Update Computed Path to an existing Managed TE Path.
260 * @param mngPath Managed TE Path to be updated
262 private void updateComputedPath(final ManagedTePath mngPath, final boolean add) {
263 checkArgument(mngPath != null, "Provided Managed TE Path is a null object");
265 final ManagedTeNode teNode = mngPath.getManagedTeNode();
267 LOG.info("Update Computed Path for Managed TE Path {}", mngPath.getLsp().getName());
269 /* Update the TE Path with the new computed path */
270 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
271 mngPath.setConfiguredLsp(
272 new ConfiguredLspBuilder(mngPath.getLsp())
273 .setPathStatus(PathStatus.Updated)
275 /* Compute new Route */
277 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
278 : pci.computeTePath(mngPath.getLsp().getIntendedPath()))
282 mngPath.addToDataStore();
284 mngPath.updateToDataStore();
287 /* Finally, update Path on PCC if it is synchronized and computed path is valid */
288 if (teNode.isSync()) {
290 mngPath.addPath(addLsp);
292 mngPath.updatePath(updateLsp);
295 mngPath.unSetTriggerFlag();
298 LOG.debug("Computed new path: {}", mngPath.getLsp().getComputedPath());
302 * Create a new Managed TE Path.
304 * @param id Managed TE Node Identifier to which the TE path is attached.
305 * @param cfgLsp TE Path.
307 * @return new or updated TE Path i.e. original TE Path augmented by a valid computed route.
309 public ConfiguredLsp createManagedTePath(final NodeId id, final ConfiguredLsp cfgLsp) {
310 checkArgument(id != null, "Provided Node ID is a null object");
311 checkArgument(cfgLsp != null, "Provided TE Path is a null object");
313 /* Check that Managed Node is registered */
314 final ManagedTeNode teNode = mngNodes.get(id);
315 if (teNode == null) {
316 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
320 /* Check if TE Path already exist or not */
321 ManagedTePath tePath = teNode.getManagedTePath(cfgLsp.key());
322 if (tePath != null) {
323 updateManagedTePath(tePath, cfgLsp);
324 tePath.updateToDataStore();
326 tePath = addManagedTePath(teNode, cfgLsp);
327 tePath.addToDataStore();
330 return tePath.getLsp();
334 * Remove TE Path to existing Managed Node. This method is called when a TE Path is deleted.
336 * @param id Managed Node ID where the TE Path is stored
337 * @param key TE Path, as Key, to be removed
339 private void removeTePath(final NodeId id, final ConfiguredLspKey key) {
340 LOG.info("Remove TE Path {} for Node {}", key, id);
342 /* Check that Managed Node is registered */
343 final ManagedTeNode teNode = mngNodes.get(id);
344 if (teNode == null) {
345 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
349 /* Get corresponding TE Path from the TE Node */
350 ManagedTePath mngPath = teNode.getManagedTePath(key);
351 if (mngPath == null) {
352 LOG.warn("Doesn't found Managed TE Path {} for TE Node {}. Abort delete operation", key, id);
357 * Delete TE Path on PCC node if it is synchronized, TE Path is Initiated and is enforced on the PCC.
358 * TE Path will be removed from Data Store once received the PcReport.
360 if (teNode.isSync() && mngPath.getType() == PathType.Initiated
361 && mngPath.getLsp().getPathStatus() == PathStatus.Sync) {
362 mngPath.removePath(removeLsp);
366 * If TE Path is not Initiated or there is a failure to remove it on PCC,
367 * remove immediately TE Path from the Data Store.
369 if (!mngPath.isSent()) {
370 unregisterTePath(id, key);
375 * Remove TE Path to existing Managed Node if TE Path has been initiated by the PCE server.
377 * @param id Managed Node ID where the TE Path is stored
378 * @param key TE Path, as Key, to be removed
380 public void deleteManagedTePath(final NodeId id, final ConfiguredLspKey key) {
381 checkArgument(id != null, "Provided Node ID is a null object");
382 checkArgument(key != null, "Provided TE Path Key is a null object");
384 /* Check that Managed Node is registered */
385 final ManagedTeNode teNode = mngNodes.get(id);
386 if (teNode == null) {
387 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
391 ManagedTePath mngPath = teNode.getManagedTePath(key);
392 if (mngPath == null) {
393 LOG.warn("Managed TE Path {} for TE Node {} doesn't exist", key, id);
398 * Start by sending corresponding Message to PCC if TE Path is initiated.
399 * TE Path will be removed when PCC confirm the deletion with PcReport.
400 * If TE Path is not initiated, the TE Path should be removed by the PCC
401 * by sending appropriate PcReport which is handle in unregisterTePath.
403 if (teNode.isSync() && mngPath.getType() == PathType.Initiated) {
404 removeTePath(id, key);
406 LOG.warn("Managed TE Path {} for TE Node {} is not managed by this PCE. Remove only configuration",
412 * Register Reported LSP as a TE Path for the PCC identified by its Node ID.
414 * @param id Node ID of the Managed Node (PCC) which report this LSP
415 * @param rptPath Reported TE Path
417 * @return Newly created or Updated Managed TE Path
419 public ManagedTePath registerTePath(final NodeId id, final ConfiguredLsp rptPath, final PathType ptype) {
420 checkArgument(id != null, "Provided Node ID is a null object");
422 /* Verify we got a valid reported TE Path */
423 if (rptPath == null) {
427 /* Check that Managed Node is registered */
428 final ManagedTeNode teNode = mngNodes.get(id);
429 if (teNode == null) {
430 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
434 LOG.info("Registered TE Path {} for Node {}", rptPath, id);
436 /* Look for existing corresponding Managed TE Path */
437 final ManagedTePath curPath = teNode.getManagedTePath(rptPath.key());
439 if (curPath == null) {
440 final ManagedTePath newPath = new ManagedTePath(teNode, pcepTopology).setType(ptype);
441 /* Check if ERO needs to be updated i.e. Path Description is empty */
442 if (rptPath.getComputedPath().getPathDescription() == null) {
443 /* Finally, update the new TE Path for this Node ID */
444 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
445 newPath.setConfiguredLsp(
446 new ConfiguredLspBuilder(rptPath)
447 .setPathStatus(PathStatus.Updated)
449 /* Complete the TE Path with Computed Route */
451 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
452 : pci.computeTePath(rptPath.getIntendedPath()))
454 /* and update Path on PCC if it is synchronized */
455 if (teNode.isSync()) {
456 newPath.updatePath(updateLsp);
459 /* Mark this TE Path as Synchronous and add it to the Managed TE Path */
460 newPath.setConfiguredLsp(new ConfiguredLspBuilder(rptPath).setPathStatus(PathStatus.Sync).build());
463 /* Update Reserved Bandwidth and Add triggers in the Connected Graph */
464 newPath.setGraph(getGraph());
466 /* Store this new reported TE Path */
467 teNode.addManagedTePath(newPath);
469 LOG.debug("Created new Managed TE Path: {}", newPath);
474 * If PCE restart, it will consider all configured TE Path as Initiated, while some of configurations
475 * concern only Delegate Path. Thus, It is necessary to verify the Path Type and correct them:
476 * i.e. a reported TE Path, if not Initiated, will overwrite an Initiated configured TE Path.
478 if (curPath.getType() == PathType.Initiated && ptype != PathType.Initiated) {
479 LOG.debug("Reset Path Type to {} for Managed TE Path {}", ptype, curPath.getLsp().getName());
480 curPath.setType(ptype);
483 /* Check this TE Path against current configuration */
484 final PathStatus newStatus = curPath.checkReportedPath(rptPath);
485 LOG.debug("Managed TE Path {} got new status {}", curPath.getLsp().getName(), newStatus);
487 /* Check if we should stop here. i.e. the Path is failed */
488 if (newStatus == PathStatus.Failed) {
489 curPath.setConfiguredLsp(new ConfiguredLspBuilder(rptPath).setPathStatus(PathStatus.Failed).build());
490 curPath.updateToDataStore();
491 /* Path is in failure. Reset Trigger Flag to authorize future path re-computation */
492 curPath.unSetTriggerFlag();
493 LOG.debug("Managed TE Path {} is in Failure", curPath);
497 /* Check if Current Path has no valid route while Reported Path has one */
498 if (curPath.getLsp().getComputedPath().getPathDescription() == null
499 && rptPath.getComputedPath().getPathDescription() != null) {
500 curPath.setConfiguredLsp(new ConfiguredLspBuilder(rptPath).setPathStatus(PathStatus.Sync).build());
501 curPath.updateGraph(getGraph());
502 curPath.updateToDataStore();
503 LOG.debug("Updated Managed TE Path with reported LSP: {}", curPath);
507 /* Check if we need to update the TE Path */
508 if (teNode.isSync() && newStatus == PathStatus.Updated) {
509 curPath.updatePath(updateLsp);
510 LOG.debug("Updated Managed TE Path {} on NodeId {}", curPath, id);
514 /* Check if TE Path becoming in SYNC */
515 if (newStatus == PathStatus.Sync && curPath.getLsp().getPathStatus() != PathStatus.Sync) {
517 curPath.updateGraph(getGraph());
518 LOG.debug("Sync Managed TE Path {} on NodeId {}", curPath, id);
522 /* Managed Path is already in SYNC, nothing to do */
527 * Remove TE Path from Operational Data Store and Path Manager.
529 * @param id Node ID of the Managed Node which own this TE Path
530 * @param key TE Path name
532 public void unregisterTePath(final NodeId id, final ConfiguredLspKey key) {
533 checkArgument(id != null, "Provided Node ID is a null object");
534 checkArgument(key != null, "Provided TE Path Key is a null object");
536 /* Verify that Node is managed by the PCE Server */
537 final ManagedTeNode teNode = mngNodes.get(id);
538 if (teNode == null) {
539 LOG.warn("There is no Managed TE Node entry for this PCC {}", id);
543 /* Remove the TE Path and associated Bandwidth if any */
544 final ManagedTePath tePath = teNode.removeManagedTePath(key);
545 if (tePath != null) {
546 tePath.unsetGraph(getGraph());
551 * Indicate that the TE Path is failed following reception of a PCE Error message.
553 * @param id Node ID of the Managed Node which own this TE Path
554 * @param key TE Path name
556 public void setTePathFailed(final NodeId id, final ConfiguredLspKey key) {
557 checkArgument(id != null, "Provided Node ID is a null object");
558 checkArgument(key != null, "Provided TE Path Key is a null object");
560 /* Verify that Node is managed by the PCE Server */
561 final ManagedTeNode teNode = mngNodes.get(id);
562 if (teNode == null) {
563 LOG.warn("There is no Managed TE Node entry for this PCC {}", id);
567 /* Get Corresponding TE Path */
568 ManagedTePath mngPath = teNode.getManagedTePath(key);
569 if (mngPath != null) {
572 LOG.warn("TE Path {} for Node {} doesn't exist", key, id);
577 * Check if a Managed TE Node is controlled by the Path Manager.
579 * @param id Node ID of the Managed TE Node
581 * @return True if Managed TE Node exist, false otherwise
583 public boolean checkManagedTeNode(final NodeId id) {
584 return mngNodes.get(id) != null;
588 * Create new Managed TE Node. This method is called by a new Managed Node is created in the Configuration
589 * Data Store. All TE Path associated to this Managed Node are also created. A new Managed Node, with TE Paths
590 * augmented with valid computed routes, is stored in the Operational Data Store.
592 * @param nodeId Managed TE Node Identifier
593 * @param pccNode Path Computation Client
595 * @return New Managed TE Node.
597 public synchronized ManagedTeNode createManagedTeNode(final NodeId nodeId, final PcepNodeConfig pccNode) {
598 checkArgument(pccNode != null, "Provided Managed TE Node is a null object");
600 /* First, create new Managed TE Node */
601 ManagedTeNode teNode = new ManagedTeNode(nodeId, chain);
602 mngNodes.put(nodeId, teNode);
604 /* Then, create all TE Paths for this Managed Node */
605 if (pccNode.getConfiguredLsp() != null) {
606 for (ConfiguredLsp tePath: pccNode.getConfiguredLsp().values()) {
607 addManagedTePath(teNode, tePath);
611 LOG.info("Created new Managed TE Node {}", nodeId);
617 * Register a PCC as a new Managed TE Node. This method is called by the PCEP Topology Listener when a new PCC
618 * connects to the PCE Server.
620 * @param id Node ID of the PCC
622 * @return current or new Managed TE Node
624 public synchronized ManagedTeNode registerManagedTeNode(final NodeId id) {
625 checkArgument(id != null, "Provided Managed Node ID is a null object");
627 ManagedTeNode teNode = mngNodes.get(id);
628 /* Create new Managed TE Node if not already exist */
629 if (teNode == null) {
630 teNode = new ManagedTeNode(id, chain);
631 mngNodes.put(id, teNode);
632 LOG.debug("Created new Managed TE Node: {}", teNode);
638 * Synchronized Managed TE Node. Once PCC finished initial report of all LSP, its state change to Synchronized.
639 * This function update the Managed TE Node status, and then parse all reported LSPs to determine if:
640 * - There is missing LSPs that need to be setup
641 * - There is LSPs that need to be updated
643 * @param id Node ID of the Managed TE Node
645 public void syncManagedTeNode(final NodeId id) {
646 checkArgument(id != null, "Provided Managed Node ID is a null object");
648 /* Verify that Node is managed by the PCE Server */
649 final ManagedTeNode teNode = mngNodes.get(id);
650 if (teNode == null) {
651 LOG.warn("There is no Managed TE Node entry for this PCC {}", id);
655 if (teNode.isSync()) {
656 LOG.debug("PCC {} is already synchronised", id);
660 /* First, mark the Node as Synchronous */
664 * PCC is synchronized, browse all Managed TE Path to check if:
665 * - some are missing i.e. apply previously initiated paths that have been created before the PCC connects
666 * - some need update i.e. apply previous modifications
667 * And for eligible Managed TE Path, give it a last chance to obtain a valid computed path. This is mandatory
668 * when ODL restart: Path Manager Configuration is read before a valid TED is available.
670 if (teNode.getTePaths() != null && !teNode.getTePaths().isEmpty()) {
671 for (ManagedTePath mngPath : teNode.getTePaths().values()) {
672 switch (mngPath.getLsp().getPathStatus()) {
674 if (mngPath.getLsp().getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
675 updateComputedPath(mngPath, false);
677 mngPath.updatePath(updateLsp);
681 if (mngPath.getLsp().getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
682 updateComputedPath(mngPath, true);
684 mngPath.addPath(addLsp);
695 * Delete Managed TE Node. This method is called when a Managed Node is removed from the Configuration Data Store.
696 * All initiated Managed TE Path own by this PCC are removed and corresponding Managed Node is removed from the
697 * Operational Data Store if it is not connected.
699 * @param nodeId Managed Node Identifier
701 public void deleteManagedTeNode(final NodeId nodeId) {
702 checkArgument(nodeId != null, "Provided Node Identifie is a null object");
704 /* Verify that Node is managed by the PCE Server */
705 final ManagedTeNode teNode = mngNodes.get(nodeId);
706 if (teNode == null) {
707 LOG.warn("Unknown Managed TE Node {}. Abort!", nodeId);
711 /* Remove all associated TE Paths that are managed by the PCE */
712 for (ManagedTePath mngPath : teNode.getTePaths().values()) {
713 if (mngPath.getType() == PathType.Initiated) {
714 removeTePath(nodeId, mngPath.getLsp().key());
718 /* Remove Managed Node from PCE Server if it is not connected */
719 if (!teNode.isSync()) {
720 mngNodes.remove(nodeId);
722 LOG.warn("Node {} is still connected. Keep Node in PCE Server.", nodeId);
727 * Call when a PCC disconnect from the PCE to disable the corresponding Managed TE Node.
729 * @param id Managed Node ID
731 public void disableManagedTeNode(final NodeId id) {
732 checkArgument(id != null, "Provided Node ID is a null object");
734 /* Verify that Node is managed by the PCE Server */
735 final ManagedTeNode teNode = mngNodes.get(id);
736 if (teNode == null) {
737 LOG.warn("Unknown Managed TE Node {}. Abort!", id);
741 /* And mark the Node as disable */
746 public void verifyVertex(final Collection<ConnectedVertexTrigger> triggers, final ConnectedVertex current,
748 for (ConnectedVertexTrigger trigger : triggers) {
749 if (trigger.verifyVertex(current, next)) {
750 updateComputedPath((ManagedTePath )trigger, false);
756 public void verifyEdge(final Collection<ConnectedEdgeTrigger> triggers, final ConnectedEdge current,
758 for (ConnectedEdgeTrigger trigger : triggers) {
759 if (trigger.verifyEdge(current, next)) {
760 updateComputedPath((ManagedTePath )trigger, false);