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 java.util.Collection;
15 import java.util.HashMap;
17 import javax.annotation.PreDestroy;
18 import org.eclipse.jdt.annotation.Nullable;
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.Transaction;
27 import org.opendaylight.mdsal.binding.api.TransactionChain;
28 import org.opendaylight.mdsal.binding.api.TransactionChainListener;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Edge;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Vertex;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathStatus;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathType;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PcepNodeConfig;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLsp;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPath;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPathBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.intended.path.ConstraintsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.NetworkTopologyPcepService;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
47 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
48 import org.osgi.service.component.annotations.Deactivate;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
53 * This Class implements the Path Manager in charge of Managed TE Node and Managed TE Path.
55 * @author Olivier Dugeon
58 public final class PathManagerProvider implements TransactionChainListener, AutoCloseable, ConnectedGraphTrigger {
59 private static final Logger LOG = LoggerFactory.getLogger(PathManagerProvider.class);
60 private final InstanceIdentifier<Topology> pcepTopology;
61 private final DataBroker dataBroker;
62 private final DefaultPceServerProvider pceServerProvider;
63 private final NetworkTopologyPcepService ntps;
64 private TransactionChain chain = null;
65 private ConnectedGraph tedGraph = null;
67 private final Map<NodeId, ManagedTeNode> mngNodes = new HashMap<NodeId, ManagedTeNode>();
69 public PathManagerProvider(final DataBroker dataBroker, KeyedInstanceIdentifier<Topology, TopologyKey> topology,
70 final NetworkTopologyPcepService ntps, final DefaultPceServerProvider pceServerProvider) {
71 this.dataBroker = requireNonNull(dataBroker);
72 this.pceServerProvider = requireNonNull(pceServerProvider);
73 this.ntps = requireNonNull(ntps);
74 this.pcepTopology = requireNonNull(topology);
75 initTransactionChain();
76 tedGraph = getGraph();
77 LOG.info("Path Manager Server started for topology {}", topology.getKey().getTopologyId().getValue());
81 * Remove the Path Manager Server and destroy the transaction chain.
87 this.tedGraph = pceServerProvider.getTedGraph();
88 if (tedGraph != null) {
89 tedGraph.unRegisterTrigger(this, InstanceIdentifier.keyOf(pcepTopology));
91 destroyTransactionChain();
94 private ConnectedGraph getGraph() {
95 if (tedGraph == null) {
96 this.tedGraph = pceServerProvider.getTedGraph();
97 if (tedGraph != null) {
98 tedGraph.registerTrigger(this, InstanceIdentifier.keyOf(pcepTopology));
105 * Reset a transaction chain by closing the current chain and starting a new one.
107 private synchronized void initTransactionChain() {
108 LOG.debug("Initializing transaction chain for Path Manager Server {}", this);
109 checkState(this.chain == null, "Transaction chain has to be closed before being initialized");
110 this.chain = dataBroker.createMergingTransactionChain(this);
114 * Destroy the current transaction chain.
116 private synchronized void destroyTransactionChain() {
117 if (this.chain != null) {
118 LOG.debug("Destroy transaction chain for Path Manager {}", this);
124 * Reset the transaction chain only so that the PingPong transaction chain
125 * will become usable again. However, there will be data loss if we do not
126 * apply the previous failed transaction again
128 protected synchronized void resetTransactionChain() {
129 LOG.debug("Resetting transaction chain for Path Manager");
130 destroyTransactionChain();
131 initTransactionChain();
135 public synchronized void onTransactionChainFailed(final TransactionChain transactionChain,
136 final Transaction transaction, final Throwable cause) {
137 LOG.error("Path Manager Provider for {} failed in transaction: {} ", pcepTopology,
138 transaction != null ? transaction.getIdentifier() : null, cause);
142 public void onTransactionChainSuccessful(final TransactionChain transactionChain) {
143 LOG.info("Path Manager Provider for {} shut down", pcepTopology);
147 * Setup Managed TE Path to existing Managed Node.
149 * @param teNode Managed TE Node where the TE Path will be enforced
150 * @param lsp TE Path to be inserted in the Managed Node
152 * @return Newly created Managed TE Path
154 private ManagedTePath addManagedTePath(final ManagedTeNode teNode, final ConfiguredLsp lsp) {
155 checkArgument(teNode != null, "Provided Managed TE Node is a null object");
156 checkArgument(lsp != null, "Provided TE Path is a null object");
158 LOG.info("Setup TE Path {} for Node {}", lsp.getName(), teNode.getId());
160 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
161 /* Create Corresponding Managed LSP */
162 final ManagedTePath mngLsp =
165 /* Complete the LSP with the Computed Route */
166 new ConfiguredLspBuilder(lsp)
167 .setPathStatus(PathStatus.Configured)
170 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
171 : pci.computeTePath(lsp.getIntendedPath()))
174 .setType(PathType.Initiated);
176 /* Store this new Managed TE Node */
177 teNode.addManagedTePath(mngLsp);
179 /* Then, setup Path on PCC if it is synchronized */
180 if (teNode.isSync()) {
181 mngLsp.addPath(ntps);
184 LOG.debug("Added new Managed LSP: {}", mngLsp);
189 * Update TE Path to existing Managed Node.
191 * @param mngPath Managed TE Path to be updated
192 * @param tePath New TE Path to be updated in the Managed Node
194 private ConfiguredLsp updateManagedTePath(final ManagedTePath mngPath, final ConfiguredLsp tePath) {
195 checkArgument(mngPath != null, "Provided Managed TE Path is a null object");
196 checkArgument(tePath != null, "Provided TE Path is a null object");
198 final ManagedTeNode teNode = mngPath.getManagedTeNode();
199 final IntendedPath iPath = tePath.getIntendedPath();
200 final IntendedPath oPath = mngPath.getLsp().getIntendedPath();
201 IntendedPathBuilder ipb = new IntendedPathBuilder(iPath);
203 LOG.info("Update TE Path {} for Node {}", mngPath.getLsp().getName(), teNode.getId());
205 /* Check that Source and Destination have not been modified and revert to old value instead */
206 if (!iPath.getSource().equals(oPath.getSource())) {
207 LOG.warn("Source IP Address {}/{} of TE Path has been modified. Revert to initial one",
208 iPath.getSource(), oPath.getSource());
209 ipb.setSource(oPath.getSource());
211 if (!iPath.getDestination().equals(oPath.getDestination())) {
212 LOG.warn("Destination IP Address {}/{} of TE Path has been modified. Revert to initial one",
213 iPath.getDestination(), oPath.getDestination());
214 ipb.setDestination(oPath.getDestination());
217 /* Same for Address Family i.e. refused to change a TE Path from RSVP-TE to Segment Routing and vice versa */
218 if (!iPath.getConstraints().getAddressFamily().equals(oPath.getConstraints().getAddressFamily())) {
219 LOG.warn("Address Family {}/{} of TE Path has been modified. Revert to initial one",
220 iPath.getConstraints().getAddressFamily(), oPath.getConstraints().getAddressFamily());
221 ipb.setConstraints(new ConstraintsBuilder(iPath.getConstraints())
222 .setAddressFamily(oPath.getConstraints().getAddressFamily()).build());
225 /* Create updated TE Path */
226 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
227 mngPath.setConfiguredLsp(
228 new ConfiguredLspBuilder(tePath)
229 .setIntendedPath(ipb.build())
230 .setPathStatus(PathStatus.Updated)
231 /* Complete it with the new Computed Route */
234 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
235 : pci.computeTePath(tePath.getIntendedPath()))
238 /* Finally, update the new TE Path for this Node ID */
239 mngPath.updateToDataStore();
241 /* Finally, update Path on PCC if it is synchronized and we computed a valid path */
242 if (teNode.isSync()) {
243 mngPath.updatePath(ntps);
246 LOG.debug("Updated Managed Paths: {}", mngPath);
247 return mngPath.getLsp();
252 * Update Computed Path to an existing Managed TE Path.
254 * @param mngPath Managed TE Path to be updated
256 private void updateComputedPath(final ManagedTePath mngPath, boolean add) {
257 checkArgument(mngPath != null, "Provided Managed TE Path is a null object");
259 final ManagedTeNode teNode = mngPath.getManagedTeNode();
261 LOG.info("Update Computed Path for Managed TE Path {}", mngPath.getLsp().getName());
263 /* Update the TE Path with the new computed path */
264 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
265 mngPath.setConfiguredLsp(
266 new ConfiguredLspBuilder(mngPath.getLsp())
267 .setPathStatus(PathStatus.Updated)
269 /* Compute new Route */
271 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
272 : pci.computeTePath(mngPath.getLsp().getIntendedPath()))
276 mngPath.addToDataStore();
278 mngPath.updateToDataStore();
281 /* Finally, update Path on PCC if it is synchronized and computed path is valid */
282 if (teNode.isSync()) {
284 mngPath.addPath(ntps);
286 mngPath.updatePath(ntps);
289 mngPath.unSetTriggerFlag();
292 LOG.debug("Computed new path: {}", mngPath.getLsp().getComputedPath());
296 * Create a new Managed TE Path.
298 * @param id Managed TE Node Identifier to which the TE path is attached.
299 * @param cfgLsp TE Path.
301 * @return new or updated TE Path i.e. original TE Path augmented by a valid computed route.
303 public ConfiguredLsp createManagedTePath(final NodeId id, ConfiguredLsp cfgLsp) {
304 checkArgument(id != null, "Provided Node ID is a null object");
305 checkArgument(cfgLsp != null, "Provided TE Path is a null object");
307 /* Check that Managed Node is registered */
308 final ManagedTeNode teNode = mngNodes.get(id);
309 if (teNode == null) {
310 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
314 /* Check if TE Path already exist or not */
315 ManagedTePath tePath = teNode.getManagedTePath(cfgLsp.key());
316 if (tePath != null) {
317 updateManagedTePath(tePath, cfgLsp);
318 tePath.updateToDataStore();
320 tePath = addManagedTePath(teNode, cfgLsp);
321 tePath.addToDataStore();
324 return tePath.getLsp();
328 * Remove TE Path to existing Managed Node. This method is called when a TE Path is deleted.
330 * @param id Managed Node ID where the TE Path is stored
331 * @param key TE Path, as Key, to be removed
333 private void removeTePath(final NodeId id, final ConfiguredLspKey key) {
334 LOG.info("Remove TE Path {} for Node {}", key, id);
336 /* Check that Managed Node is registered */
337 final ManagedTeNode teNode = mngNodes.get(id);
338 if (teNode == null) {
339 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
343 /* Get corresponding TE Path from the TE Node */
344 ManagedTePath mngPath = teNode.getManagedTePath(key);
345 if (mngPath == null) {
346 LOG.warn("Doesn't found Managed TE Path {} for TE Node {}. Abort delete operation", key, id);
351 * Delete TE Path on PCC node if it is synchronized, TE Path is Initiated and is enforced on the PCC.
352 * TE Path will be removed from Data Store once received the PcReport.
354 if (teNode.isSync() && mngPath.getType() == PathType.Initiated
355 && mngPath.getLsp().getPathStatus() == PathStatus.Sync) {
356 mngPath.removePath(ntps);
360 * If TE Path is not Initiated or there is a failure to remove it on PCC,
361 * remove immediately TE Path from the Data Store.
363 if (!mngPath.isSent()) {
364 unregisterTePath(id, key);
369 * Remove TE Path to existing Managed Node if TE Path has been initiated by the PCE server.
371 * @param id Managed Node ID where the TE Path is stored
372 * @param key TE Path, as Key, to be removed
374 public void deleteManagedTePath(final NodeId id, final ConfiguredLspKey key) {
375 checkArgument(id != null, "Provided Node ID is a null object");
376 checkArgument(key != null, "Provided TE Path Key is a null object");
378 /* Check that Managed Node is registered */
379 final ManagedTeNode teNode = mngNodes.get(id);
380 if (teNode == null) {
381 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
385 ManagedTePath mngPath = teNode.getManagedTePath(key);
386 if (mngPath == null) {
387 LOG.warn("Managed TE Path {} for TE Node {} doesn't exist", key, id);
392 * Start by sending corresponding Message to PCC if TE Path is initiated.
393 * TE Path will be removed when PCC confirm the deletion with PcReport.
394 * If TE Path is not initiated, the TE Path should be removed by the PCC
395 * by sending appropriate PcReport which is handle in unregisterTePath.
397 if (teNode.isSync() && mngPath.getType() == PathType.Initiated) {
398 removeTePath(id, key);
400 LOG.warn("Managed TE Path {} for TE Node {} is not managed by this PCE. Remove only configuration",
406 * Register Reported LSP as a TE Path for the PCC identified by its Node ID.
408 * @param id Node ID of the Managed Node (PCC) which report this LSP
409 * @param rptPath Reported TE Path
411 * @return Newly created or Updated Managed TE Path
413 public ManagedTePath registerTePath(NodeId id, final ConfiguredLsp rptPath, final PathType ptype) {
414 checkArgument(id != null, "Provided Node ID is a null object");
416 /* Verify we got a valid reported TE Path */
417 if (rptPath == null) {
421 /* Check that Managed Node is registered */
422 final ManagedTeNode teNode = mngNodes.get(id);
423 if (teNode == null) {
424 LOG.warn("Managed TE Node {} is not registered. Cancel transaction!", id);
428 LOG.info("Registered TE Path {} for Node {}", rptPath, id);
430 /* Look for existing corresponding Managed TE Path */
431 final ManagedTePath curPath = teNode.getManagedTePath(rptPath.key());
433 if (curPath == null) {
434 final ManagedTePath newPath = new ManagedTePath(teNode, pcepTopology).setType(ptype);
435 /* Check if ERO needs to be updated i.e. Path Description is empty */
436 if (rptPath.getComputedPath().getPathDescription() == null) {
437 /* Finally, update the new TE Path for this Node ID */
438 final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
439 newPath.setConfiguredLsp(
440 new ConfiguredLspBuilder(rptPath)
441 .setPathStatus(PathStatus.Updated)
443 /* Complete the TE Path with Computed Route */
445 ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
446 : pci.computeTePath(rptPath.getIntendedPath()))
448 /* and update Path on PCC if it is synchronized */
449 if (teNode.isSync()) {
450 newPath.updatePath(ntps);
453 /* Mark this TE Path as Synchronous and add it to the Managed TE Path */
454 newPath.setConfiguredLsp(new ConfiguredLspBuilder(rptPath).setPathStatus(PathStatus.Sync).build());
457 /* Update Reserved Bandwidth and Add triggers in the Connected Graph */
458 newPath.setGraph(getGraph());
460 /* Store this new reported TE Path */
461 teNode.addManagedTePath(newPath);
463 LOG.debug("Created new Managed TE Path: {}", newPath);
468 * If PCE restart, it will consider all configured TE Path as Initiated, while some of configurations
469 * concern only Delegate Path. Thus, It is necessary to verify the Path Type and correct them:
470 * i.e. a reported TE Path, if not Initiated, will overwrite an Initiated configured TE Path.
472 if (curPath.getType() == PathType.Initiated && ptype != PathType.Initiated) {
473 LOG.debug("Reset Path Type to {} for Managed TE Path {}", ptype, curPath.getLsp().getName());
474 curPath.setType(ptype);
477 /* Check this TE Path against current configuration */
478 final PathStatus newStatus = curPath.checkReportedPath(rptPath);
479 LOG.debug("Managed TE Path {} got new status {}", curPath.getLsp().getName(), newStatus);
481 /* Check if we should stop here. i.e. the Path is failed */
482 if (newStatus == PathStatus.Failed) {
483 curPath.setConfiguredLsp(new ConfiguredLspBuilder(rptPath).setPathStatus(PathStatus.Failed).build());
484 curPath.updateToDataStore();
485 /* Path is in failure. Reset Trigger Flag to authorize future path re-computation */
486 curPath.unSetTriggerFlag();
487 LOG.debug("Managed TE Path {} is in Failure", curPath);
491 /* Check if Current Path has no valid route while Reported Path has one */
492 if ((curPath.getLsp().getComputedPath().getPathDescription() == null)
493 && (rptPath.getComputedPath().getPathDescription() != null)) {
494 curPath.setConfiguredLsp(new ConfiguredLspBuilder(rptPath).setPathStatus(PathStatus.Sync).build());
495 curPath.updateGraph(getGraph());
496 curPath.updateToDataStore();
497 LOG.debug("Updated Managed TE Path with reported LSP: {}", curPath);
501 /* Check if we need to update the TE Path */
502 if (teNode.isSync() && newStatus == PathStatus.Updated) {
503 curPath.updatePath(ntps);
504 LOG.debug("Updated Managed TE Path {} on NodeId {}", curPath, id);
508 /* Check if TE Path becoming in SYNC */
509 if (newStatus == PathStatus.Sync && curPath.getLsp().getPathStatus() != PathStatus.Sync) {
511 curPath.updateGraph(getGraph());
512 LOG.debug("Sync Managed TE Path {} on NodeId {}", curPath, id);
516 /* Managed Path is already in SYNC, nothing to do */
521 * Remove TE Path from Operational Data Store and Path Manager.
523 * @param id Node ID of the Managed Node which own this TE Path
524 * @param key TE Path name
526 public void unregisterTePath(final NodeId id, final ConfiguredLspKey key) {
527 checkArgument(id != null, "Provided Node ID is a null object");
528 checkArgument(key != null, "Provided TE Path Key is a null object");
530 /* Verify that Node is managed by the PCE Server */
531 final ManagedTeNode teNode = mngNodes.get(id);
532 if (teNode == null) {
533 LOG.warn("There is no Managed TE Node entry for this PCC {}", id);
537 /* Remove the TE Path and associated Bandwidth if any */
538 final ManagedTePath tePath = teNode.removeManagedTePath(key);
539 if (tePath != null) {
540 tePath.unsetGraph(getGraph());
545 * Indicate that the TE Path is failed following reception of a PCE Error message.
547 * @param id Node ID of the Managed Node which own this TE Path
548 * @param key TE Path name
550 public void setTePathFailed(final NodeId id, final ConfiguredLspKey key) {
551 checkArgument(id != null, "Provided Node ID is a null object");
552 checkArgument(key != null, "Provided TE Path Key is a null object");
554 /* Verify that Node is managed by the PCE Server */
555 final ManagedTeNode teNode = mngNodes.get(id);
556 if (teNode == null) {
557 LOG.warn("There is no Managed TE Node entry for this PCC {}", id);
561 /* Get Corresponding TE Path */
562 ManagedTePath mngPath = teNode.getManagedTePath(key);
563 if (mngPath != null) {
566 LOG.warn("TE Path {} for Node {} doesn't exist", key, id);
571 * Check if a Managed TE Node is controlled by the Path Manager.
573 * @param id Node ID of the Managed TE Node
575 * @return True if Managed TE Node exist, false otherwise
577 public boolean checkManagedTeNode(final NodeId id) {
578 return (mngNodes.get(id) != null);
582 * Create new Managed TE Node. This method is called by a new Managed Node is created in the Configuration
583 * Data Store. All TE Path associated to this Managed Node are also created. A new Managed Node, with TE Paths
584 * augmented with valid computed routes, is stored in the Operational Data Store.
586 * @param nodeId Managed TE Node Identifier
587 * @param pccNode Path Computation Client
589 * @return New Managed TE Node.
591 public synchronized ManagedTeNode createManagedTeNode(final NodeId nodeId, final PcepNodeConfig pccNode) {
592 checkArgument(pccNode != null, "Provided Managed TE Node is a null object");
594 /* First, create new Managed TE Node */
595 ManagedTeNode teNode = new ManagedTeNode(nodeId, chain);
596 mngNodes.put(nodeId, teNode);
598 /* Then, create all TE Paths for this Managed Node */
599 if (pccNode.getConfiguredLsp() != null) {
600 for (ConfiguredLsp tePath: pccNode.getConfiguredLsp().values()) {
601 addManagedTePath(teNode, tePath);
605 LOG.info("Created new Managed TE Node {}", nodeId);
611 * Register a PCC as a new Managed TE Node. This method is called by the PCEP Topology Listener when a new PCC
612 * connects to the PCE Server.
614 * @param id Node ID of the PCC
616 * @return current or new Managed TE Node
618 public synchronized ManagedTeNode registerManagedTeNode(final NodeId id) {
619 checkArgument(id != null, "Provided Managed Node ID is a null object");
621 ManagedTeNode teNode = mngNodes.get(id);
622 /* Create new Managed TE Node if not already exist */
623 if (teNode == null) {
624 teNode = new ManagedTeNode(id, chain);
625 mngNodes.put(id, teNode);
626 LOG.debug("Created new Managed TE Node: {}", teNode);
632 * Synchronized Managed TE Node. Once PCC finished initial report of all LSP, its state change to Synchronized.
633 * This function update the Managed TE Node status, and then parse all reported LSPs to determine if:
634 * - There is missing LSPs that need to be setup
635 * - There is LSPs that need to be updated
637 * @param id Node ID of the Managed TE Node
639 public void syncManagedTeNode(final NodeId id) {
640 checkArgument(id != null, "Provided Managed Node ID is a null object");
642 /* Verify that Node is managed by the PCE Server */
643 final ManagedTeNode teNode = mngNodes.get(id);
644 if (teNode == null) {
645 LOG.warn("There is no Managed TE Node entry for this PCC {}", id);
649 if (teNode.isSync()) {
650 LOG.debug("PCC {} is already synchronised", id);
654 /* First, mark the Node as Synchronous */
658 * PCC is synchronized, browse all Managed TE Path to check if:
659 * - some are missing i.e. apply previously initiated paths that have been created before the PCC connects
660 * - some need update i.e. apply previous modifications
661 * And for eligible Managed TE Path, give it a last chance to obtain a valid computed path. This is mandatory
662 * when ODL restart: Path Manager Configuration is read before a valid TED is available.
664 if (teNode.getTePaths() != null && !teNode.getTePaths().isEmpty()) {
665 for (ManagedTePath mngPath : teNode.getTePaths().values()) {
666 switch (mngPath.getLsp().getPathStatus()) {
668 if (mngPath.getLsp().getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
669 updateComputedPath(mngPath, false);
671 mngPath.updatePath(ntps);
675 if (mngPath.getLsp().getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
676 updateComputedPath(mngPath, true);
678 mngPath.addPath(ntps);
689 * Delete Managed TE Node. This method is called when a Managed Node is removed from the Configuration Data Store.
690 * All initiated Managed TE Path own by this PCC are removed and corresponding Managed Node is removed from the
691 * Operational Data Store if it is not connected.
693 * @param nodeId Managed Node Identifier
695 public void deleteManagedTeNode(final NodeId nodeId) {
696 checkArgument(nodeId != null, "Provided Node Identifie is a null object");
698 /* Verify that Node is managed by the PCE Server */
699 final ManagedTeNode teNode = mngNodes.get(nodeId);
700 if (teNode == null) {
701 LOG.warn("Unknown Managed TE Node {}. Abort!", nodeId);
705 /* Remove all associated TE Paths that are managed by the PCE */
706 for (ManagedTePath mngPath : teNode.getTePaths().values()) {
707 if (mngPath.getType() == PathType.Initiated) {
708 removeTePath(nodeId, mngPath.getLsp().key());
712 /* Remove Managed Node from PCE Server if it is not connected */
713 if (!teNode.isSync()) {
714 mngNodes.remove(nodeId);
716 LOG.warn("Node {} is still connected. Keep Node in PCE Server.", nodeId);
721 * Call when a PCC disconnect from the PCE to disable the corresponding Managed TE Node.
723 * @param id Managed Node ID
725 public void disableManagedTeNode(final NodeId id) {
726 checkArgument(id != null, "Provided Node ID is a null object");
728 /* Verify that Node is managed by the PCE Server */
729 final ManagedTeNode teNode = mngNodes.get(id);
730 if (teNode == null) {
731 LOG.warn("Unknown Managed TE Node {}. Abort!", id);
735 /* And mark the Node as disable */
740 public void verifyVertex(Collection<ConnectedVertexTrigger> triggers, @Nullable ConnectedVertex current,
741 @Nullable Vertex next) {
742 for (ConnectedVertexTrigger trigger : triggers) {
743 if (trigger.verifyVertex(current, next)) {
744 updateComputedPath((ManagedTePath )trigger, false);
750 public void verifyEdge(Collection<ConnectedEdgeTrigger> triggers, @Nullable ConnectedEdge current,
751 @Nullable Edge next) {
752 for (ConnectedEdgeTrigger trigger : triggers) {
753 if (trigger.verifyEdge(current, next)) {
754 updateComputedPath((ManagedTePath )trigger, false);