Correct Bugs in Path Manager 05/100205/4
authorOlivier Dugeon <olivier.dugeon@orange.com>
Mon, 21 Mar 2022 13:53:16 +0000 (14:53 +0100)
committerOlivier Dugeon <olivier.dugeon@orange.com>
Wed, 23 Mar 2022 16:35:38 +0000 (17:35 +0100)
Some major bugs are corrected with this patch:
- METRIC Object is not sent to PCC during creation or Update
  due to a redundant setting in yang model. The patch suppress
  the 'routing-method' and deduce the type of metric from what
  metric has been set in constraint (like for Algorithm)
- After closing ODL, previous updated configuration on delegated
  LSP are considered as Initiated LSP letting the possibility
  to delete LSP while it is not initiated. The patch overwrites
  the LSP type with one provided by the PcReport if there is
  mismatch between Initiated type
- Saved Managed TE Path are not applied to PCCi at startup.
  Indeed, saved configuration are read before the Graph is
  available. Thus, no valid paths are computed and Managed TE
  Paths are marked with NO_PATH. Give a chance to compute a
  valid path when PCC goes in SYNC to validate configured LSP
  and thus applied modification on PCC.
- Change the HashMap of Managed TE Node to store the TE Managed
  Path to a ConcurrentHashMap. This is mandatory when removing
  the Managed TE Node in order to safetly loop other all Managed
  TE Paths attached to this Managed TE Node.

Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Change-Id: Ie737cafe7938e6ec0886c75d9f76f9f00f7163a9

docs/pcep/pcep-user-guide-pce-server.rst
pcep/server/server-api/src/main/yang/pcep-server.yang
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/ManagedTeNode.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/ManagedTePath.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathComputationImpl.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathManagerListener.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathManagerProvider.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PcepTopologyListener.java

index 031b776e780b7e8570867bff852312ab81ae25fa..5949584a7477bbf7d36109a76c95eac4a4c5561f 100644 (file)
@@ -132,7 +132,6 @@ schema:
        +--ro intended-path
        |  +--ro source?           inet:ip-address
        |  +--ro destination?      inet:ip-address
-       |  +--ro routing-method?   routing-type
        |  +--ro constraints
        |     +--ro metric?           uint32
        |     +--ro te-metric?        uint32
@@ -219,7 +218,6 @@ operational (with ``?content=nonconfig``) and onfiguration (with
                                 "intended-path": {
                                     "destination": "10.2.2.2",
                                     "source": "10.1.1.1",
-                                    "routing-method": "te-metric",
                                     "constraints": {
                                         "bandwidth": "100000",
                                         "class-type": 1,
@@ -257,7 +255,6 @@ path are also reported:
                                 "intended-path": {
                                     "destination": "10.1.1.1",
                                     "source": "10.2.2.2",
-                                    "routing-method": "te-metric",
                                     "constraints": {
                                         "bandwidth": "100000",
                                         "class-type": 1,
@@ -314,7 +311,7 @@ the configuration as follow:
 
 .. code-block:: json
    :linenos:
-   :emphasize-lines: 4,8,9,13
+   :emphasize-lines: 4,8,11,12
 
     {
         "pcep-server:configured-lsp": [
@@ -323,7 +320,6 @@ the configuration as follow:
                 "intended-path": {
                     "destination": "10.2.2.2",
                     "source": "10.1.1.1",
-                    "routing-method": "te-metric",
                     "constraints": {
                         "bandwidth": "100000",
                         "class-type": 1,
@@ -335,17 +331,17 @@ the configuration as follow:
         ]
     }
 
-@line 5: **name** The tunnel identifier. Must be unique.
+@line 4: **name** The tunnel identifier. Must be unique.
 
-@line 8: **routing-method** Specify which type of metric is used to compute
-the path: ``metric`` (standard), ``te-metric`` (TE metric) or ``delay``
-
-@line 9: **constraints** Constraints that the path compputation algorithm
+@line 8: **constraints** Constraints that the path compputation algorithm
 should respect to determine the path of the tunnel. Note that if no path
 is found, the tunnel is not enforced in the PCC and ``computation-status``
 within the ``computed-path`` is set to failed.
 
-@line 13: **address-family** Indicate the IP family of the tunnel: ``ipv4`` or
+@line 11: Specify which type of metric is used to compute the path:
+``metric`` (standard IGP metric), ``te-metric`` (TE metric) or ``delay``
+
+@line 12: **address-family** Indicate the IP family of the tunnel: ``ipv4`` or
 ``ipv6`` for IPv4 respectively IPv6 RSVP-TE tunnel, ``sr-ipv4`` or ``sr-ipv6``
 for IPv4 respectively IPv6 Segment Routing tunnel.
 
index 3729f3862d0cb2e863a17a95f01d2cac96b867b2..a1367241f90bc5c77966b49cda7f6d4ffb002eb1 100644 (file)
@@ -23,6 +23,12 @@ module pcep-server {
         accompanies this distribution, and is available at
         http://www.eclipse.org/legal/epl-v10.html";
 
+    revision "2022-03-21" {
+        description
+            "Del LSP routing method and path type. Add computed path metric.";
+        reference "";
+    }
+
     revision "2021-07-20" {
         description
              "Initial revision.";
@@ -51,25 +57,6 @@ module pcep-server {
         }
     }
 
-    typedef routing-type {
-        description "Various objectives for the Path Computation Algorithm";
-        type enumeration {
-            enum none {
-                value 0;
-            }
-            enum metric {
-                value 1;
-            }
-            enum te-metric {
-                value 2;
-            }
-            enum delay {
-                value 3;
-            }
-        }
-        default "none";
-    }
-
     typedef path-status {
         description "Status of the TE Path";
         type enumeration {
@@ -106,13 +93,6 @@ module pcep-server {
                 type string;
                 mandatory true;
             }
-            /*
-            leaf path-type {
-                description "Type of the TE Path";
-                type path-type;
-                config false;
-            }
-            */
             leaf path-status {
                 description "Status of TE Path";
                 type path-status;
@@ -126,9 +106,6 @@ module pcep-server {
                 leaf destination {
                     type inet:ip-address;
                 }
-                leaf routing-method {
-                     type routing-type;
-                }
                 container constraints {
                     uses algo:path-constraints;
                 }
index 5c079c49fdcbe0109737f171db75b046fde12971..c685a2e09ab71348f041915948470a5f1df1f1a3 100644 (file)
@@ -10,13 +10,13 @@ package org.opendaylight.bgpcep.pcep.server.provider;
 import static com.google.common.base.Preconditions.checkArgument;
 
 import com.google.common.base.MoreObjects;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import org.opendaylight.mdsal.binding.api.TransactionChain;
 import org.opendaylight.mdsal.binding.api.WriteTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLsp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLspKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yangtools.yang.binding.CodeHelpers;
 import org.slf4j.Logger;
@@ -32,7 +32,8 @@ public class ManagedTeNode {
 
     private final NodeId id;
     private NodeState state;
-    private Map<ConfiguredLspKey, ManagedTePath> mngPaths = new HashMap<ConfiguredLspKey, ManagedTePath>();
+    private ConcurrentMap<ConfiguredLspKey, ManagedTePath> mngPaths =
+            new ConcurrentHashMap<ConfiguredLspKey, ManagedTePath>();
     private final TransactionChain chain;
     private static final Logger LOG = LoggerFactory.getLogger(ManagedTeNode.class);
 
@@ -56,7 +57,7 @@ public class ManagedTeNode {
         return id;
     }
 
-    public Map<ConfiguredLspKey, ManagedTePath> getTePaths() {
+    public ConcurrentMap<ConfiguredLspKey, ManagedTePath> getTePaths() {
         return mngPaths;
     }
 
index d3fb941dc02a52b199200ddfa16661db04760acd..58a44c65a21382f61a8f89b79294a9383f3688f4 100644 (file)
@@ -34,13 +34,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.com
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Arguments2Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Arguments3Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.lsp.object.LspBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathComputationClient1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLsp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLspBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.IntendedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.intended.path.Constraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathComputationClient1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.intended.path.Constraints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.BandwidthBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv4CaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv6CaseBuilder;
@@ -404,10 +404,7 @@ public class ManagedTePath {
                 .setAdministrative(true)
                 .setDelegate(true);
 
-        /*
-         * Build Arguments.
-         * Note that TE Metric and Delay are not set because, at least, Juniper Routers don't support them.
-         */
+        /* Build Arguments. */
         final ArgumentsBuilder args = new ArgumentsBuilder()
                 .setEndpointsObj(epb.build())
                 .setEro(MessagesUtil.getEro(cfgLsp.getComputedPath().getPathDescription()))
@@ -416,14 +413,22 @@ public class ManagedTePath {
                         .setPathSetupType(pstBuilder.build())
                         .build());
 
-        /* with Bandwidth and Standard Metric */
+        /* with Bandwidth and Metric if defined */
         if (iPath.getConstraints().getBandwidth() != null) {
             final int ftoi = Float.floatToIntBits(iPath.getConstraints().getBandwidth().getValue().floatValue());
             final byte[] itob = { (byte) (0xFF & ftoi >> 24), (byte) (0xFF & ftoi >> 16), (byte) (0xFF & ftoi >> 8),
                 (byte) (0xFF & ftoi) };
             args.setBandwidth(new BandwidthBuilder().setBandwidth(new Bandwidth(itob)).build());
         }
-        if (iPath.getConstraints().getMetric() != null) {
+        /* Note that Delay are not set because, at least, Juniper Routers don't support them */
+        if (iPath.getConstraints().getTeMetric() != null) {
+            final MetricBuilder metricBuilder = new MetricBuilder()
+                    .setComputed(true)
+                    .setMetricType(Uint8.TWO)
+                    .setValue(new Float32(ByteBuffer.allocate(4)
+                            .putFloat(iPath.getConstraints().getTeMetric().floatValue()).array()));
+            args.setMetrics(Collections.singletonList(new MetricsBuilder().setMetric(metricBuilder.build()).build()));
+        } else if (iPath.getConstraints().getMetric() != null) {
             final MetricBuilder metricBuilder = new MetricBuilder()
                     .setComputed(true)
                     .setMetricType(Uint8.ONE)
@@ -534,13 +539,29 @@ public class ManagedTePath {
                     .build())
                 .setEro(MessagesUtil.getEro(cfgLsp.getComputedPath().getPathDescription()));
 
-        /*  with Bandwidth if defined, but not other Metrics as some routers don't support them */
+        /*  with Bandwidth and Metric if defined */
         if (iPath.getConstraints().getBandwidth() != null) {
             final int ftoi = Float.floatToIntBits(iPath.getConstraints().getBandwidth().getValue().floatValue());
             final byte[] itob = { (byte) (0xFF & ftoi >> 24), (byte) (0xFF & ftoi >> 16), (byte) (0xFF & ftoi >> 8),
                 (byte) (0xFF & ftoi) };
             args.setBandwidth(new BandwidthBuilder().setBandwidth(new Bandwidth(itob)).build());
         }
+        /* Note that Delay are not set because, at least, Juniper Routers don't support them */
+        if (iPath.getConstraints().getTeMetric() != null) {
+            final MetricBuilder metricBuilder = new MetricBuilder()
+                    .setComputed(true)
+                    .setMetricType(Uint8.TWO)
+                    .setValue(new Float32(ByteBuffer.allocate(4)
+                            .putFloat(iPath.getConstraints().getTeMetric().floatValue()).array()));
+            args.setMetrics(Collections.singletonList(new MetricsBuilder().setMetric(metricBuilder.build()).build()));
+        } else if (iPath.getConstraints().getMetric() != null) {
+            final MetricBuilder metricBuilder = new MetricBuilder()
+                    .setComputed(true)
+                    .setMetricType(Uint8.ONE)
+                    .setValue(new Float32(
+                            ByteBuffer.allocate(4).putFloat(iPath.getConstraints().getMetric().floatValue()).array()));
+            args.setMetrics(Collections.singletonList(new MetricsBuilder().setMetric(metricBuilder.build()).build()));
+        }
 
         /*
          * NOTE: Seems that ClassType is not supported by some routers. Skip it for the moment.
index f688e9879009156e6fd3943504189251a0a5f46f..1ae9b9db4d7afff74c6c16a659fb6a73672937dc 100644 (file)
@@ -29,10 +29,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.com
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathConstraints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.get.constrained.path.input.ConstraintsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.RoutingType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.ComputedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.IntendedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPath;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.Bandwidth;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassType;
@@ -136,20 +135,12 @@ public class PathComputationImpl implements PathComputation {
 
         /* Determine Path Computation Algorithm according to parameters */
         AlgorithmType algoType;
-        final RoutingType rt = intend.getRoutingMethod();
-        switch (rt) {
-            case Metric:
-                algoType = AlgorithmType.Spf;
-                break;
-            case TeMetric:
-                algoType = AlgorithmType.Cspf;
-                break;
-            case Delay:
-                algoType = AlgorithmType.Samcra;
-                break;
-            default:
-                algoType = AlgorithmType.Spf;
-                break;
+        if (intend.getConstraints().getDelay() != null) {
+            algoType = AlgorithmType.Samcra;
+        } else if (intend.getConstraints().getTeMetric() != null) {
+            algoType = AlgorithmType.Cspf;
+        } else {
+            algoType = AlgorithmType.Spf;
         }
         PathComputationAlgorithm algo = algoProvider.getPathComputationAlgorithm(tedGraph, algoType);
         if (algo == null) {
index 313d6c9457d5f0f7b6711967bcab718981e145b7..67a06d67ac8501fb7d988ce0ae06f1a8f3b8caa5 100644 (file)
@@ -18,8 +18,8 @@ import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PcepNodeConfig;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PcepNodeConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLsp;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
@@ -80,13 +80,13 @@ public final class PathManagerListener implements DataTreeChangeListener<Node>,
             switch (lsp.getModificationType()) {
                 case DELETE:
                     cfgLsp = (ConfiguredLsp) lsp.getDataBefore();
-                    LOG.debug("Un-Register Managed TE Path: {}", cfgLsp.getName());
+                    LOG.debug("Delete Managed TE Path: {}", cfgLsp.getName());
                     pathManager.deleteManagedTePath(nodeId, cfgLsp.key());
                     break;
                 case SUBTREE_MODIFIED:
                 case WRITE:
                     cfgLsp = (ConfiguredLsp) lsp.getDataAfter();
-                    LOG.debug("Register Managed TE Path {}", cfgLsp.getName());
+                    LOG.debug("Update Managed TE Path {}", cfgLsp);
                     pathManager.createManagedTePath(nodeId, cfgLsp);
                     break;
                 default:
index b663673db1ee79047e6eb8e1f064f995c3fd49d0..afb0e0c1b6973ed7eb9a69ce066ca1d9b57d70f4 100644 (file)
@@ -19,15 +19,16 @@ import org.opendaylight.mdsal.binding.api.Transaction;
 import org.opendaylight.mdsal.binding.api.TransactionChain;
 import org.opendaylight.mdsal.binding.api.TransactionChainListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PcepNodeConfig;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLsp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLspBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLspKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.IntendedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.IntendedPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PcepNodeConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.intended.path.ConstraintsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.NetworkTopologyPcepService;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
@@ -130,18 +131,21 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
 
         LOG.info("Setup TE Path {} for Node {}", lsp.getName(), teNode.getId());
 
-        /* Complete the LSP with the Computed Route */
-        ConfiguredLspBuilder clb = new ConfiguredLspBuilder(lsp)
-                .setPathStatus(PathStatus.Configured);
         final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
-        if (pci != null) {
-            clb.setComputedPath(pci.computeTePath(lsp.getIntendedPath()));
-        } else {
-            clb.setComputedPath(new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build());
-        }
-
         /* Create Corresponding Managed LSP */
-        final ManagedTePath mngLsp = new ManagedTePath(teNode, clb.build(), pcepTopology).setType(PathType.Initiated);
+        final ManagedTePath mngLsp =
+            new ManagedTePath(
+                    teNode,
+                    /* Complete the LSP with the Computed Route */
+                    new ConfiguredLspBuilder(lsp)
+                        .setPathStatus(PathStatus.Configured)
+                        .setComputedPath(
+                            pci == null
+                                ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
+                                : pci.computeTePath(lsp.getIntendedPath()))
+                        .build(),
+                    pcepTopology)
+                .setType(PathType.Initiated);
 
         /* Store this new Managed TE Node */
         teNode.addManagedTePath(mngLsp);
@@ -184,30 +188,29 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
                     iPath.getDestination(), oPath.getDestination());
             ipb.setDestination(oPath.getDestination());
         }
-        /*
-         * Same for Routing Method: i.e. refused to change a TE Path from
-         * RSVP-TE to Segment Routing and vice versa
-         */
-        if (!iPath.getRoutingMethod().equals(oPath.getRoutingMethod())) {
-            LOG.warn("Routing Method {}/{} of TE Path has been modified. Revert to initial one",
-                    iPath.getRoutingMethod(), oPath.getRoutingMethod());
-            ipb.setRoutingMethod(oPath.getRoutingMethod());
+
+        /* Same for Address Family i.e. refused to change a TE Path from RSVP-TE to Segment Routing and vice versa */
+        if (!iPath.getConstraints().getAddressFamily().equals(oPath.getConstraints().getAddressFamily())) {
+            LOG.warn("Address Family {}/{} of TE Path has been modified. Revert to initial one",
+                    iPath.getConstraints().getAddressFamily(), oPath.getConstraints().getAddressFamily());
+            ipb.setConstraints(new ConstraintsBuilder(iPath.getConstraints())
+                    .setAddressFamily(oPath.getConstraints().getAddressFamily()).build());
         }
 
         /* Create updated TE Path */
-        ConfiguredLspBuilder clb = new ConfiguredLspBuilder(tePath)
-                .setIntendedPath(ipb.build())
-                .setPathStatus(PathStatus.Updated);
-        /* Complete it with the new Computed Route */
         final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
-        if (pci != null) {
-            clb.setComputedPath(pci.computeTePath(tePath.getIntendedPath()));
-        } else {
-            clb.setComputedPath(new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build());
-        }
+        mngPath.setConfiguredLsp(
+            new ConfiguredLspBuilder(tePath)
+                .setIntendedPath(ipb.build())
+                .setPathStatus(PathStatus.Updated)
+                /* Complete it with the new Computed Route */
+                .setComputedPath(
+                    pci == null
+                        ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
+                        : pci.computeTePath(tePath.getIntendedPath()))
+                .build());
 
         /* Finally, update the new TE Path for this Node ID */
-        mngPath.setConfiguredLsp(clb.build());
         mngPath.updateToDataStore();
 
         /* Finally, update Path on PCC if it is synchronized and we computed a valid path */
@@ -219,6 +222,48 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
         return mngPath.getLsp();
     }
 
+    /**
+     * Update Computed Path to an existing Managed TE Path.
+     *
+     * @param mngPath  Managed TE Path to be updated
+     */
+    private void updateComputedPath(final ManagedTePath mngPath, boolean add) {
+        checkArgument(mngPath != null, "Provided Managed TE Path is a null object");
+
+        final ManagedTeNode teNode = mngPath.getManagedTeNode();
+
+        LOG.info("Update Computed Path for Managed TE Path {}", mngPath.getLsp().getName());
+
+        /* Update the TE Path with the new computed path */
+        final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
+        mngPath.setConfiguredLsp(
+            new ConfiguredLspBuilder(mngPath.getLsp())
+                .setPathStatus(PathStatus.Updated)
+                .setComputedPath(
+                    /* Compute new Route */
+                    pci == null
+                        ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
+                        : pci.computeTePath(mngPath.getLsp().getIntendedPath()))
+                .build());
+
+        if (add) {
+            mngPath.addToDataStore();
+        } else {
+            mngPath.updateToDataStore();
+        }
+
+        /* Finally, update Path on PCC if it is synchronized and computed path is valid */
+        if (teNode.isSync()) {
+            if (add) {
+                mngPath.addPath(ntps);
+            } else {
+                mngPath.updatePath(ntps);
+            }
+        }
+
+        LOG.debug("Computed new path: {}", mngPath.getLsp().getComputedPath());
+    }
+
     /**
      * Create a new Managed TE Path.
      *
@@ -359,31 +404,26 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
 
         if (curPath == null) {
             final ManagedTePath newPath = new ManagedTePath(teNode, pcepTopology).setType(ptype);
-            final ConfiguredLspBuilder clb = new ConfiguredLspBuilder(rptPath);
-
             /* Check if ERO needs to be updated i.e. Path Description is empty */
             if (rptPath.getComputedPath().getPathDescription() == null) {
-                clb.setPathStatus(PathStatus.Updated);
-                /* Complete the TE Path with Computed Route */
-                final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
-                if (pci != null) {
-                    clb.setComputedPath(pci.computeTePath(rptPath.getIntendedPath()));
-                } else {
-                    clb.setComputedPath(
-                            new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build());
-                }
-
                 /* Finally, update the new TE Path for this Node ID */
-                newPath.setConfiguredLsp(clb.build());
-
+                final PathComputationImpl pci = (PathComputationImpl) pceServerProvider.getPathComputation();
+                newPath.setConfiguredLsp(
+                    new ConfiguredLspBuilder(rptPath)
+                        .setPathStatus(PathStatus.Updated)
+                        .setComputedPath(
+                            /* Complete the TE Path with Computed Route */
+                            pci == null
+                                ? new ComputedPathBuilder().setComputationStatus(ComputationStatus.Failed).build()
+                                : pci.computeTePath(rptPath.getIntendedPath()))
+                        .build());
                 /* and update Path on PCC if it is synchronized */
                 if (teNode.isSync()) {
                     newPath.updatePath(ntps);
                 }
             } else {
                 /* Mark this TE Path as Synchronous and add it to the Managed TE Path */
-                clb.setPathStatus(PathStatus.Sync);
-                newPath.setConfiguredLsp(clb.build());
+                newPath.setConfiguredLsp(new ConfiguredLspBuilder(rptPath).setPathStatus(PathStatus.Sync).build());
             }
 
             /* Update Reserved Bandwidth in the Connected Graph */
@@ -396,6 +436,16 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
             return newPath;
         }
 
+        /*
+         * If PCE restart, it will consider all configured TE Path as Initiated, while some of configurations
+         * concern only Delegate Path. Thus, It is necessary to verify the Path Type and correct them:
+         * i.e. a reported TE Path, if not Initiated, will overwrite an Initiated configured TE Path.
+         */
+        if (curPath.getType() == PathType.Initiated && ptype != PathType.Initiated) {
+            LOG.debug("Reset Path Type to {} for Managed TE Path {}", ptype, curPath.getLsp().getName());
+            curPath.setType(ptype);
+        }
+
         /* Check this TE Path against current configuration */
         final PathStatus newStatus = curPath.checkReportedPath(rptPath);
         LOG.debug("Managed TE Path {} got new status {}", curPath.getLsp().getName(), newStatus);
@@ -575,20 +625,32 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
         teNode.sync();
 
         /*
-         * PCC is synchronized, browse all TE Path to check if:
+         * PCC is synchronized, browse all Managed TE Path to check if:
          *  - some are missing i.e. apply previously initiated paths that have been created before the PCC connects
          *  - some need update i.e. apply previous modifications
+         * And for eligible Managed TE Path, give it a last chance to obtain a valid computed path. This is mandatory
+         * when ODL restart: Path Manager Configuration is read before a valid TED is available.
          */
-        for (ManagedTePath mngPath : teNode.getTePaths().values()) {
-            switch (mngPath.getLsp().getPathStatus()) {
-                case Updated:
-                    mngPath.updatePath(ntps);
-                    break;
-                case Configured:
-                    mngPath.addPath(ntps);
-                    break;
-                default:
-                    break;
+        if (teNode.getTePaths() != null && !teNode.getTePaths().isEmpty()) {
+            for (ManagedTePath mngPath : teNode.getTePaths().values()) {
+                switch (mngPath.getLsp().getPathStatus()) {
+                    case Updated:
+                        if (mngPath.getLsp().getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
+                            updateComputedPath(mngPath, false);
+                        } else {
+                            mngPath.updatePath(ntps);
+                        }
+                        break;
+                    case Configured:
+                        if (mngPath.getLsp().getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
+                            updateComputedPath(mngPath, true);
+                        } else {
+                            mngPath.addPath(ntps);
+                        }
+                        break;
+                    default:
+                        break;
+                }
             }
         }
     }
@@ -611,7 +673,7 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
         }
 
         /* Remove all associated TE Paths that are managed by the PCE */
-        for (ManagedTePath mngPath: teNode.getTePaths().values()) {
+        for (ManagedTePath mngPath : teNode.getTePaths().values()) {
             if (mngPath.getType() == PathType.Initiated) {
                 removeTePath(nodeId, mngPath.getLsp().key());
             }
@@ -643,5 +705,4 @@ public final class PathManagerProvider implements TransactionChainListener, Auto
         /* And mark the Node as disable */
         teNode.disable();
     }
-
 }
index 478bfff658387d0a43b1c143ec52334e337a0f4f..e1ebeb1ebee385acd66c1894d54e6bc7fce5388e 100644 (file)
@@ -41,15 +41,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.iet
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev200720.SrSubobject;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev200720.sr.subobject.nai.IpAdjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev200720.sr.subobject.nai.IpNodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.RoutingType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLsp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLspBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLspKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.IntendedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.intended.path.ConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.ConfiguredLspKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.intended.path.ConstraintsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.reported.route.object.Rro;
@@ -391,22 +390,18 @@ public final class PcepTopologyListener implements DataTreeChangeListener<Node>,
             convert = ByteBuffer.wrap(path.getReoptimizationBandwidth().getBandwidth().getValue()).getFloat();
             cb.setBandwidth(new DecimalBandwidth(BigDecimal.valueOf(convert.longValue())));
         }
-        RoutingType rtype = RoutingType.None;
         if (path.getMetrics() != null) {
             for (Metrics metric: path.getMetrics()) {
                 convert = ByteBuffer.wrap(metric.getMetric().getValue().getValue()).getFloat();
                 switch (metric.getMetric().getMetricType().intValue()) {
                     case MessagesUtil.IGP_METRIC:
                         cb.setMetric(Uint32.valueOf(convert.longValue()));
-                        rtype = RoutingType.Metric;
                         break;
                     case MessagesUtil.TE_METRIC:
                         cb.setTeMetric(Uint32.valueOf(convert.longValue()));
-                        rtype = RoutingType.TeMetric;
                         break;
                     case MessagesUtil.PATH_DELAY:
                         cb.setDelay(new Delay(Uint32.valueOf(convert.longValue())));
-                        rtype = RoutingType.Delay;
                         break;
                     default:
                         break;
@@ -443,7 +438,6 @@ public final class PcepTopologyListener implements DataTreeChangeListener<Node>,
         final IntendedPathBuilder ipb = new IntendedPathBuilder()
                 .setSource(source)
                 .setDestination(destination)
-                .setRoutingMethod(rtype)
                 .setConstraints(cb.build());
 
         /* Build Actual Path */