New API for GNPy 37/99937/1
authoratriki <ahmed.triki@orange.com>
Fri, 4 Feb 2022 11:14:01 +0000 (12:14 +0100)
committerGilles Thouenon <gilles.thouenon@orange.com>
Thu, 3 Mar 2022 07:37:01 +0000 (08:37 +0100)
- add new yang files of the api
- update the code
- remove node identification by IP address

JIRA: TRNSPRTPCE-513
Change-Id: I530323561cb3640b7082d4b5e2f22e782b2057b2
Signed-off-by: Ahmed Triki <ahmed.triki@orange.com>
34 files changed:
api/src/main/yang/gnpy-api@2019-01-03.yang [deleted file]
api/src/main/yang/gnpy-api@2022-02-21.yang [new file with mode: 0644]
api/src/main/yang/gnpy-eqpt-config@2018-11-19.yang [deleted file]
api/src/main/yang/gnpy-eqpt-config@2022-02-21.yang [new file with mode: 0644]
api/src/main/yang/gnpy-network-topology@2022-02-21.yang [moved from api/src/main/yang/gnpy-network-topology@2021-08-31.yang with 53% similarity]
api/src/main/yang/gnpy-path-computation-simplified@2020-09-09.yang [deleted file]
api/src/main/yang/gnpy-path-computation-simplified@2022-02-21.yang [new file with mode: 0644]
common/src/main/java/org/opendaylight/transportpce/common/fixedflex/GridConstant.java
common/src/main/java/org/opendaylight/transportpce/common/fixedflex/GridUtils.java
common/src/test/java/org/opendaylight/transportpce/common/converter/JsonStringConverterTest.java
common/src/test/resources/expected_string.json
common/src/test/resources/gnpy_request.json
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyServiceImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyTopoImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyApiModule.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyConsumer.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyConsumerImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyResource.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyStatus.java [new file with mode: 0644]
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/JsonConfigurator.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/RequestSerializer.java [moved from pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyApiSerializer.java with 63% similarity]
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/ResultDeserializer.java
pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java
pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyConsumerTest.java
pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyStub.java
pce/src/test/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImplTest.java
pce/src/test/resources/gnpy/gnpy_request.json
pce/src/test/resources/gnpy/gnpy_result_no_path.json
pce/src/test/resources/gnpy/gnpy_status.json [new file with mode: 0644]
tests/sample_configs/gnpy/openroadmTopology.json
tests/transportpce_tests/pce/test03_gnpy.py
tox.ini

diff --git a/api/src/main/yang/gnpy-api@2019-01-03.yang b/api/src/main/yang/gnpy-api@2019-01-03.yang
deleted file mode 100644 (file)
index e0d5348..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-module gnpy-api {
-  yang-version 1;
-  namespace "gnpy:gnpy-api";
-  prefix gnpyapi;
-
-  import gnpy-network-topology {
-    prefix gnpynt;
-  }
-  import gnpy-path-computation-simplified {
-    prefix gnpypc;
-  }
-
-  organization
-    "Telecom Infra Project OOPT PSE Working Group";
-  contact
-    "WG Web:   <https://github.com/Telecominfraproject/oopt-gnpy>
-     contact:  <mailto:ahmed.triki@orange.com>
-     contact:  <mailto:esther.lerouzic@orange.com>
-    ";
-  description
-    "YANG model for gnpy api input for path computation - TransportPCE preversion";
-
-  revision 2019-01-03 {
-    description
-      "first draft";
-    reference
-      "YANG model for api input for path computation with gnpy";
-  }
-
-  container gnpy-api {
-    description
-      "This is the structure of the body of the request to gnpy";
-    container topology-file {
-      description
-        "Describe the topology file to connect to gnpy";
-      uses gnpynt:topo;
-    }
-    container service-file {
-      description
-        "Describe the service file to connect to gnpy";
-      uses gnpypc:service;
-    }
-  }
-}
diff --git a/api/src/main/yang/gnpy-api@2022-02-21.yang b/api/src/main/yang/gnpy-api@2022-02-21.yang
new file mode 100644 (file)
index 0000000..75e530c
--- /dev/null
@@ -0,0 +1,97 @@
+module gnpy-api {
+  yang-version 1.1;
+  namespace "gnpy:gnpy-api";
+  prefix gnpyapi;
+
+  import gnpy-network-topology {
+    prefix gnpynt;
+  }
+  import gnpy-path-computation-simplified {
+    prefix gnpypc;
+  }
+  import gnpy-eqpt-config {
+    prefix gnpyeqpt;
+  }
+
+  organization
+    "Telecom Infra Project OOPT PSE Working Group";
+  contact
+    "WG Web:   <https://github.com/Telecominfraproject/oopt-gnpy>
+     contact:  <mailto:ahmed.triki@orange.com>
+     contact:  <mailto:esther.lerouzic@orange.com>
+    ";
+  description
+    "YANG model for gnpy api input for path computation -
+    The license used for all the yang files of GNPy is BSD 3-Clause License
+
+    BSD 3-Clause License
+
+    Copyright (c) 2018, Telecom Infra Project
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    * Neither the name of the copyright holder nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2022-02-21 {
+    description
+      "draft for GNPy4TPCE preversion - non official version relevant for v2.4 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
+  revision 2020-10-22 {
+    description
+      "draft for experimental/2020-candi";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
+  revision 2019-01-03 {
+    description
+      "first draft for GNPy4TPCE preversion - non official version relevant for v1.2 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
+  container request {
+    container service {
+      description
+        "Describe the service file to connect to gnpy";
+      uses gnpypc:service;
+    }
+    container topology {
+      description
+        "Describe the topology file to connect to gnpy";
+      uses gnpynt:topo;
+    }
+    container equipment {
+      description
+        "Describe the equipment library to connect to gnpy";
+      uses gnpyeqpt:eqpt;
+    }
+  }
+
+
+}
\ No newline at end of file
diff --git a/api/src/main/yang/gnpy-eqpt-config@2018-11-19.yang b/api/src/main/yang/gnpy-eqpt-config@2018-11-19.yang
deleted file mode 100644 (file)
index 23fa129..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-module gnpy-eqpt-config {
-  yang-version 1;
-  namespace "gnpy:gnpy-eqpt-config";
-  prefix gnpyeqpt;
-
-  organization
-    "Telecom Infra Project OOPT PSE
-     Working Group";
-  contact
-    "WG Web:   <https://github.com/Telecominfraproject/oopt-gnpy>
-     contact:  <mailto:ahmed.triki@orange.com>
-     contact:  <mailto:esther.lerouzic@orange.com>
-    ";
-  description
-    "Base YANG model for gnpy equipment library input for path computation - transportPCE preversion";
-
-  revision 2018-11-19 {
-    description
-      "first draft";
-    reference
-      "Base YANG model for equipment library input for path computation with gnpy";
-  }
-
-  /*
-   * Identities
-
-  identity edfa-variety {
-    description "edfa variety" ;
-  }
-
-  identity fiber-variety {
-    description "base identity for fiber variety" ;
-  }
-
-  identity transceiver-variety {
-    description "base identity for transceiver variety" ;
-  }
-
-   */
-
-  list Edfa {
-    key "type_variety";
-    leaf type_variety {
-      type string;
-      description
-        "a unique name to ID the amplifier in the JSON/Excel template topology input file";
-    }
-  }
-  list Fiber {
-    key "type_variety";
-    description
-      "a unique name to ID the fiber in the JSON or Excel template topology input file";
-    leaf type_variety {
-      type string;
-    }
-  }
-  list Transceiver {
-    key "type_variety";
-    description
-      "a unique name to ID the transceiver in the JSON or Excel template topology input file";
-    leaf type_variety {
-      type string;
-    }
-  }
-  list mode {
-    key "format";
-    leaf format {
-      type string;
-      description
-        "unique name of the mode";
-    }
-  }
-  container Spans;
-  container Roadms;
-  container SI;
-}
diff --git a/api/src/main/yang/gnpy-eqpt-config@2022-02-21.yang b/api/src/main/yang/gnpy-eqpt-config@2022-02-21.yang
new file mode 100644 (file)
index 0000000..603d56d
--- /dev/null
@@ -0,0 +1,483 @@
+module gnpy-eqpt-config {
+  yang-version 1;
+  namespace "gnpy:gnpy-eqpt-config";
+
+  prefix "gnpyeqpt";
+
+  organization
+    "Telecom Infra Project OOPT PSE
+     Working Group";
+
+  contact
+    "WG Web:   <https://github.com/Telecominfraproject/oopt-gnpy>
+     contact:  <mailto:ahmed.triki@orange.com>
+     contact:  <mailto:esther.lerouzic@orange.com>
+   ";
+
+  description
+    "Base YANG model for gnpy equipment library input -
+    The license used for all the yang files of GNPy is BSD 3-Clause License
+
+    BSD 3-Clause License
+
+    Copyright (c) 2018, Telecom Infra Project
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    * Neither the name of the copyright holder nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2022-02-21 {
+    description
+      "draft for GNPy4TPCE preversion - non official version relevant for v2.4 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
+  revision 2020-10-22 {
+    description "draft for experimental/2020-candi";
+    reference "Base YANG model for equipment library input for path computation with gnpy";
+  }
+
+  revision 2019-01-03 {
+    description
+      "first draft for GNPy4TPCE preversion - non official version relevant for v1.2 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
+  identity edfa-type-def {
+    description "base identity for variable gain and fixed gain";
+  }
+
+  identity variable-gain{
+    base edfa-type-def ;
+    description "'variable_gain' is a simplified model simulating a 2-coil
+      EDFA with internal, input and output VOAs. The NF vs gain response is calculated
+      accordingly based on the input parameters: nf_min, nf_max, and gain_flatmax. It
+      is not a simple interpolation but a 2-stage NF calculation.";
+  }
+
+  identity fixed-gain{
+    base edfa-type-def ;
+    description "'fixed_gain' is a fixed gain model. NF == Cte == nf0 if gain_min < gain < gain_flatmax";
+  }
+
+  identity fiber-variety {
+    description "base identity for fiber variety";
+  }
+
+  identity transceiver-variety {
+    description "base identity for transceiver variety";
+  }
+
+
+  grouping variable-gain {
+    leaf nf_min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+    }
+    leaf nf_max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+    }
+    leaf out_voa_auto{
+      type boolean ;
+      description "auto_design feature to optimize the amplifier output VOA. If true, output VOA is present
+      and will be used to push amplifier gain to its maximum, within EOL power margins.";
+    }
+  }
+
+  grouping fixed-gain{
+    leaf nf0 {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+    }
+  }
+
+  grouping no-type-def{
+    leaf advanced_config_from_json {
+      type string ;
+      description " filename with json edfa";
+
+    }
+  }
+
+
+  grouping openroadm{
+    leaf-list nf_coef {
+      type decimal64 {
+        fraction-digits 5;
+      }
+      //default [8.1e-4,6.142e-2,1.558,19.97] ;
+    }
+  }
+
+  grouping dual-stage {
+    leaf raman {
+      type boolean;
+    }
+    leaf preamp_variety {
+      type leafref {
+          path "../../Edfa/type_variety";
+        }
+    }
+    leaf booster_variety {
+      type leafref {
+          path "../../Edfa/type_variety";
+        }
+    }
+  }
+
+  grouping edfa-common {
+    leaf allowed_for_design{
+      type boolean ;
+      description "If false, the amplifier will not be picked by auto-design but it can still be used as a
+      manual input (from JSON or Excel template topology files.)";
+    }
+    leaf gain_flatmax {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+    }
+    leaf gain_min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+    }
+    leaf p_max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+    }
+    leaf type_def {
+      type identityref{
+        base edfa-type-def ;
+      }
+    }
+    choice type_of_model {
+      case variable-gain {
+        when "type_def = 'variable-gain'";
+        uses variable-gain ;
+      }
+      case fixed-gain{
+        when "type_def = 'fixed-gain'";
+        uses fixed-gain;
+      }
+      case no-type-def{
+        when "type_def = 'no-type-def'";
+        uses no-type-def;
+      }
+      case openroadm{
+        when "type_def = 'openroadm'";
+        uses openroadm;
+      }
+      case dual_stage {
+        when "type_def = 'dual_stage'";
+        uses dual-stage ;
+      }
+    }
+  }
+
+  grouping common-fiber {
+    description "common parameters for fiber and raman fiber";
+    leaf type_variety {
+      type string ;
+      }
+    leaf dispersion{
+      type decimal64 {
+        fraction-digits 8;
+      }
+      units s.m-1.m-1;
+    }
+    leaf gamma{
+      type decimal64 {
+        fraction-digits 8;
+      }
+      units w-1.m-1 ;
+      description "2pi.n2/(lambda*Aeff) (w-2.m-1)";
+    }
+    leaf pmd_coef{
+      type decimal64 {
+        fraction-digits 16;
+      }
+      units s.sqrt(m)-1;
+    }
+  }
+
+  grouping eqpt{
+    list Edfa {
+      key type_variety;
+      leaf type_variety {
+        type string;
+        description "a unique name to ID the amplifier in the JSON/Excel template topology input file";
+      }
+      uses edfa-common;
+    }
+
+    list Fiber {
+      key type_variety;
+      uses common-fiber;
+    }
+
+    list RamanFiber {
+      uses common-fiber;
+      container raman_efficiency {
+        leaf-list cr {
+          type decimal64 {
+            fraction-digits 8;
+          }
+        }
+        leaf-list frequency_offset {
+          type decimal64 {
+            fraction-digits 8;
+          }
+        }
+      }
+    }
+
+    list Span {
+      leaf power_mode {
+        type boolean ;
+      }
+      leaf-list delta_power_range_db {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf max_length {
+        type decimal64 {
+          fraction-digits 2;
+        }
+        units km;
+        default 150.0 ;
+      }
+      leaf max_loss {
+        type decimal64 {
+          fraction-digits 2;
+        }
+        units dB;
+      }
+      leaf max_fiber_lineic_loss_for_raman {
+        type decimal64 {
+          fraction-digits 2;
+        }
+        units dB.km-1;
+      }
+      leaf target_extended_gain {
+        type decimal64 {
+          fraction-digits 2;
+        }
+        units dB;
+      }
+      leaf length_units{
+        type string ;
+        default "km";
+      }
+      leaf padding{
+        type decimal64 {
+          fraction-digits 2;
+        }
+        default 10.0 ;
+      }
+      leaf EOL{
+         type decimal64 {
+          fraction-digits 2;
+        }
+        default 0.0 ;
+      }
+      leaf con_in{
+        type decimal64 {
+          fraction-digits 2;
+        }
+        default 0.0 ;
+      }
+      leaf con_out{
+        type decimal64 {
+          fraction-digits 2;
+        }
+        default 0.0 ;
+      }
+    }
+
+    list Roadm {
+      leaf target_pch_out_db {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf add_drop_osnr {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf pmd {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      container restrictions {
+        leaf-list preamp_variety_list {
+          type string;
+        }
+        leaf-list booster_variety_list {
+          type string;
+        }
+      }
+    }
+
+    list SI {
+      leaf f_min {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf f_max {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf baud_rate {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf spacing {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf power_dbm {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf-list power_range_db {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf roll_off {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf tx_osnr {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      leaf sys_margins {
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+    }
+
+    list Transceiver {
+      leaf type_variety {
+        type string ;
+        description "a unique name to ID the transceiver in the JSON or Excel template topology input file";
+      }
+      container frequency {
+        leaf min {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          units Hz ;
+        }
+        leaf max {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          units Hz ;
+        }
+        description "Min/max frequency of transponder eg 191.35e12  and 196.1e12";
+      }
+      list mode {
+        leaf format {
+          type string ;
+          description "unique name of the mode";
+        }
+        leaf baud_rate {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          units baud ;
+          description "baud_rate";
+        }
+        leaf OSNR {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          units dB ;
+          description "min required OSNR in 0.1nm (dB)";
+        }
+        leaf tx_osnr {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          units dB ;
+          description "min required OSNR in 0.1nm (dB)";
+        }
+        leaf min_spacing {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          units GHz ;
+          description "...";
+        }
+        leaf bit_rate {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          units bit/s ;
+          description "bit rate";
+        }
+        leaf roll_off {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          description "...";
+        }
+        leaf cost {
+          type decimal64 {
+              fraction-digits 2;
+            }
+          description "arbitrary unit";
+        }
+      }
+    }
+  }
+}
+
similarity index 53%
rename from api/src/main/yang/gnpy-network-topology@2021-08-31.yang
rename to api/src/main/yang/gnpy-network-topology@2022-02-21.yang
index b20f1ed30f4fb530d5c155c48d0996ee7170c3d9..390831780bd9ac2049ba7be1882a872310281ecf 100644 (file)
@@ -1,10 +1,7 @@
 module gnpy-network-topology {
-  yang-version 1;
+  yang-version 1.1;
   namespace "gnpy:gnpy-network-topology";
   prefix gnpynt;
-  import ietf-inet-types {
-    prefix inet;
-  }
 
   organization
     "Telecom Infra Project OOPT PSE Working Group";
@@ -14,20 +11,60 @@ module gnpy-network-topology {
      contact:  <mailto:esther.lerouzic@orange.com>
     ";
   description
-    "YANG model for gnpy network input for path computation - transportPCE preversion";
+    "YANG model for gnpy network input -
+    The license used for all the yang files of GNPy is BSD 3-Clause License
+
+    BSD 3-Clause License
+
+    Copyright (c) 2018, Telecom Infra Project
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
 
-  revision 2021-08-31 {
+    * Neither the name of the copyright holder nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2022-02-21 {
     description
-      "Change absolute path in leafref";
+      "draft for GNPy4TPCE preversion - non official version relevant for v2.4 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
   }
 
-  revision 2018-12-14 {
+  revision 2020-10-22 {
     description
-      "first draft";
+      "draft for experimental/2020-candi";
     reference
       "YANG model for network input for path computation with gnpy";
   }
 
+  revision 2019-01-03 {
+    description
+      "first draft for GNPy4TPCE preversion - non official version relevant for v1.2 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
   identity type-element {
     description
       "Base identity for element type";
@@ -42,7 +79,7 @@ module gnpy-network-topology {
   identity Fiber {
     base type-element;
     description
-      "Fiber element";
+      "Fiber element (unidirectional)";
   }
 
   identity Roadm {
@@ -60,7 +97,9 @@ module gnpy-network-topology {
   identity Fused {
     base type-element;
     description
-      "Fused element";
+      "Fused element ; non amplified connection between two fiber spans ;
+       can be used to model optical distribution frame, or losses due to
+       connectors or fused in a span";
   }
 
   identity length-unit {
@@ -86,16 +125,6 @@ module gnpy-network-topology {
     }
   }
 
-  typedef te-node-id {
-    type inet:ip-address;
-    description
-      "An identifier for a node in a topology.
-       The identifier is represented as 32-bit unsigned integer in
-       the dotted-quad notation.
-       This attribute is mapped to Router ID in
-       RFC3630, RFC5329, RFC5305, and RFC6119.";
-  }
-
   typedef Coef {
     type decimal64 {
       fraction-digits 2;
@@ -137,6 +166,8 @@ module gnpy-network-topology {
         fraction-digits 2;
       }
       mandatory true;
+      units db/km;
+      description "Loss coefficient of the fiber span (dB/km)";
     }
     leaf length_units {
       type identityref {
@@ -148,18 +179,21 @@ module gnpy-network-topology {
       type decimal64 {
         fraction-digits 2;
       }
+      units "dB";
       mandatory true;
     }
     leaf con_in {
       type decimal64 {
         fraction-digits 2;
       }
+      units "dB";
       mandatory true;
     }
     leaf con_out {
       type decimal64 {
         fraction-digits 2;
       }
+      units "dB";
       mandatory true;
     }
   }
@@ -168,16 +202,16 @@ module gnpy-network-topology {
     container operational {
       description
         "Operational values for the Edfa ";
-      leaf gain-target {
+      leaf gain_target {
         type decimal64 {
           fraction-digits 2;
         }
         units "dB";
         mandatory true;
         description
-          "..";
+          "gain target of the amplifier (before VOA and after att_in)";
       }
-      leaf tilt-target {
+      leaf tilt_target {
         type decimal64 {
           fraction-digits 2;
         }
@@ -185,7 +219,7 @@ module gnpy-network-topology {
         description
           "..";
       }
-      leaf out-voa {
+      leaf out_voa {
         type decimal64 {
           fraction-digits 2;
         }
@@ -194,6 +228,15 @@ module gnpy-network-topology {
         description
           "..";
       }
+      leaf delta_p {
+        type decimal64 {
+          fraction-digits 2;
+        }
+        units "dB";
+        mandatory true;
+        description
+          "per channel target output power delta with respect to power setting in SI";
+      }
     }
   }
 
@@ -206,11 +249,32 @@ module gnpy-network-topology {
       description
         "..";
     }
+    container restrictions {
+      leaf-list preamp_variety_list {
+        type string;
+        description
+          "List of authorized preamp type-variety";
+      }
+      leaf-list booster_variety_list {
+        type string;
+        description
+          "List of authorized booster type-variety";
+      }
+    }
   }
 
   grouping transceiver-params;
 
-  grouping fused-params;
+  grouping fused-params{
+    leaf loss {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units "dB";
+      description
+        "Concentrated loss of the fused element";
+    }
+  }
 
   grouping element-type-choice {
     choice element-type {
@@ -220,7 +284,7 @@ module gnpy-network-topology {
       }
       case FiberRoadm {
         container params {
-          choice fiberroadm {
+          choice fiberroadmfused {
             case Fiber {
               when "type = 'Fiber'";
               uses fiber-params;
@@ -229,18 +293,20 @@ module gnpy-network-topology {
               when "type = 'Roadm'";
               uses roadm-params;
             }
+            case Fused {
+              when "type = 'Fused'";
+              uses fused-params;
+            }
           }
         }
       }
       case Transceiver {
         when "type = 'Transceiver'";
       }
-      case Fused {
-        when "type = 'Fused'";
-      }
     }
   }
 
+
   grouping topo {
     list elements {
       key "uid";
@@ -266,12 +332,12 @@ module gnpy-network-topology {
       config false;
       leaf from_node {
         type leafref {
-          path ../../elements/uid;
+          path "../../elements/uid";
         }
       }
       leaf to_node {
         type leafref {
-          path ../../elements/uid;
+          path "../../elements/uid";
         }
       }
     }
diff --git a/api/src/main/yang/gnpy-path-computation-simplified@2020-09-09.yang b/api/src/main/yang/gnpy-path-computation-simplified@2020-09-09.yang
deleted file mode 100644 (file)
index 0299fbe..0000000
+++ /dev/null
@@ -1,632 +0,0 @@
-module gnpy-path-computation-simplified {
-  yang-version 1;
-  namespace "gnpy:path";
-  prefix gnpypc;
-
-  import ietf-inet-types {
-    prefix inet;
-  }
-
-  organization
-    "Telecom Infra Project OOPT PSE Working Group";
-  contact
-    "WG Web:   <https://github.com/Telecominfraproject/oopt-gnpy>
-     contact:  <mailto:ahmed.triki@orange.com>
-     contact:  <mailto:esther.lerouzic@orange.com>
-    ";
-  description
-    "YANG model for gnpy path computation simplified for transportPCE";
-
-  revision 2020-09-09 {
-    description
-      "remove key from route-object-include-exclude";
-  }
-  revision 2020-02-02 {
-    description
-      "second draft with detailed blocking reasons";
-    reference
-      "YANG model for path computation with gnpy inputs";
-  }
-
-  identity SNR-bandwidth {
-    base path-metric-type;
-    description
-      "A metric that records SNR in signal bandwidth";
-  }
-
-  identity OSNR-bandwidth {
-    base path-metric-type;
-    description
-      "A metric that records OSNR in signal bandwidth";
-  }
-
-  identity SNR-0.1nm {
-    base path-metric-type;
-    description
-      "A metric that records SNR in 0.1nm";
-  }
-
-  identity OSNR-0.1nm {
-    base path-metric-type;
-    description
-      "A metric that records OSNR in 0.1nm";
-  }
-
-  identity reference_power {
-    base path-metric-type;
-    description
-      "to be revised";
-  }
-
-  identity path_bandwidth {
-    base path-metric-type;
-    description
-      "to be revised";
-  }
-
-  identity path-metric-type {
-    description
-      "Base identity for path metric type";
-  }
-
-  identity route-usage-type {
-    description
-      "Base identity for route usage";
-  }
-
-  identity route-include-ero {
-    base route-usage-type;
-    description
-      "Include ERO from route";
-  }
-
-  identity route-exclude-ero {
-    base route-usage-type;
-    description
-      "Exclude ERO from route";
-  }
-
-  identity route-exclude-srlg {
-    base route-usage-type;
-    description
-      "Exclude SRLG from route";
-  }
-
-  typedef te-hop-type {
-    type enumeration {
-      enum LOOSE {
-        description
-          "loose hop in an explicit path";
-      }
-      enum STRICT {
-        description
-          "strict hop in an explicit path";
-      }
-    }
-    description
-      "enumerated type for specifying loose or strict
-       paths";
-    reference
-      "RFC3209: section-4.3.2";
-  }
-
-  typedef te-path-disjointness {
-    type bits {
-      bit node {
-        position 0;
-        description
-          "Node disjoint.";
-      }
-      bit link {
-        position 1;
-        description
-          "Link disjoint.";
-      }
-      bit srlg {
-        position 2;
-        description
-          "SRLG (Shared Risk Link Group) disjoint.";
-      }
-    }
-    description
-      "Type of the resource disjointness for a TE tunnel path.";
-    reference
-      "RFC4872: RSVP-TE Extensions in Support of End-to-End
-       Generalized Multi-Protocol Label Switching (GMPLS)
-       Recovery";
-  } // te-path-disjointness
-
-  typedef te-node-id {
-    type inet:ip-address;
-    description
-      "An identifier for a node in a topology.
-       The identifier is represented as 32-bit unsigned integer in
-       the dotted-quad notation.
-       This attribute is mapped to Router ID in
-       RFC3630, RFC5329, RFC5305, and RFC6119.";
-  }
-
-  typedef te-tp-id {
-    type union {
-      type uint32; // Unnumbered
-      type inet:ip-address; // IPv4 or IPv6 address
-    }
-    description
-      "An identifier for a TE link endpoint on a node.
-       This attribute is mapped to local or remote link identifier in
-       RFC3630 and RFC5305.";
-  }
-
-  typedef accumulated-metric-type {
-    type union {
-      type uint64;
-      type decimal64 {
-        fraction-digits 2;
-      }
-    }
-    description
-      "type useable for accumulative-value";
-  }
-
-  grouping effective-freq-slot {
-    /* content copied from ietf-flexi-grid-media-channel, because only M and N are needed
-       from the initial grouping.
-     */
-    description
-      "The effective frequency slot is an attribute
-       of a media channel and, being a frequency slot, it is
-       described by its nominal central frequency and slot
-       width";
-    reference
-      "rfc7698";
-    leaf N {
-      type int32;
-      description
-        "Is used to determine the Nominal Central
-         Frequency. The set of nominal central frequencies
-         can be built using the following expression:
-           f = 193.1 THz + n x 0.00625 THz,
-         where 193.1 THz is ITU-T ''anchor frequency'' for
-         transmission over the C band, n is a positive or
-         negative integer including 0.";
-      reference
-        "rfc7698";
-    }
-    leaf M {
-      type int32;
-      description
-        "Is used to determine the slot width. A slot width
-         is constrained to be M x SWG (that is, M x 12.5 GHz),
-         where M is an integer greater than or equal to 1.";
-      reference
-        "rfc7698";
-    }
-  }
-
-  grouping gnpy-specific-parameters {
-    description
-      "This grouping defines the gnpy specific parameters for requests.";
-    leaf technology {
-      type string;
-      default "flexi-grid";
-      description
-        "Data plane technology type.";
-    }
-    leaf trx_type {
-      type string;
-      mandatory true;
-      description
-        "name of the transponder type (to be read from equipment library";
-    }
-    leaf trx_mode {
-      type string;
-      description
-        "name of the transponder mode (to be read from equipment library";
-    }
-    list effective-freq-slot {
-      key "N";
-      uses effective-freq-slot;
-    }
-    leaf spacing {
-      type decimal64 {
-        fraction-digits 1;
-      }
-      units "Hz";
-      mandatory true;
-      description
-        "It is the spacing between channels assuming full load with
-         same channels as the requested one. multiple of 12.5 GHz";
-    }
-    leaf max-nb-of-channel {
-      type uint32;
-      description
-        "Nb of channel to take into account for the full load case.\n";
-    }
-    leaf output-power {
-      type decimal64 {
-        fraction-digits 5;
-      }
-      units "W";
-      description
-        "optical power setting to be used for the propagation";
-    }
-    leaf path_bandwidth {
-      type decimal64 {
-        fraction-digits 5;
-      }
-      units "bit/s";
-      mandatory true;
-      description
-        "Capacity required";
-    }
-  }
-
-  grouping transponder {
-    leaf transponder-type {
-      type string;
-      description
-        "transponder type.";
-    }
-    leaf transponder-mode {
-      type string;
-      description
-        "transponder mode.";
-    }
-  }
-
-  grouping hop-attribute {
-    description
-      "This grouping defines the hop attribute parameters for request or response";
-    choice hop-type {
-      case tsp {
-        container transponder {
-          uses transponder;
-        }
-      }
-      case regen {
-        container regenerator {
-          leaf regenerator-id {
-            type string;
-          }
-          uses transponder;
-        }
-      }
-      case pow {
-        container optical-power {
-          leaf optical-power {
-            type decimal64 {
-              fraction-digits 5;
-            }
-            units "W";
-            description
-              "hop output (input??) power";
-          }
-        }
-      }
-    }
-  }
-
-  grouping path-route-objects {
-    description
-      "List of EROs to be included or excluded when performing
-       the path computation.";
-    container explicit-route-objects {
-      description
-        "Container for the route object list";
-      list route-object-include-exclude {
-        description
-          "List of explicit route objects to include or
-           exclude in path computation";
-        leaf explicit-route-usage {
-          type identityref {
-            base route-usage-type;
-          }
-          description
-            "Explicit-route usage.";
-        }
-        uses explicit-route-hop;
-      }
-    }
-  }
-
-  grouping generic-path-disjointness {
-    description
-      "Path disjointness grouping";
-    leaf disjointness {
-      type te-path-disjointness;
-      description
-        "The type of resource disjointness.
-         Under primary path, disjointness level applies to
-         all secondary LSPs. Under secondary, disjointness
-         level overrides the one under primary";
-    }
-  }
-
-  grouping common-path-constraints-attributes {
-    description
-      "Common path constraints configuration grouping";
-    uses common-constraints_config;
-  }
-
-  grouping generic-path-constraints {
-    description
-      "Global named path constraints configuration
-       grouping";
-    container path-constraints {
-      description
-        "TE named path constraints container";
-      uses common-path-constraints-attributes;
-    }
-  }
-
-  grouping explicit-route-hop {
-    description
-      "The explicit route subobject grouping";
-    leaf index {
-      type uint32;
-      description
-        "ERO subobject index";
-    }
-    choice type {
-      description
-        "The explicit route subobject type";
-      case num-unnum-hop {
-        container num-unnum-hop {
-          description
-            "Numbered and Unnumbered link/node explicit route
-             subobject";
-          leaf node-id {
-            //type te-node-id;
-            type string;
-            description
-              "The identifier of a node in the TE topology.";
-          }
-          leaf link-tp-id {
-            //type te-tp-id;
-            type string;
-            description
-              "TE link termination point identifier. The combination
-               of TE link ID and the TE node ID is used to identify an
-               unnumbered TE link.";
-          }
-          leaf hop-type {
-            type te-hop-type;
-            description
-              "strict or loose hop";
-          }
-        }
-      }
-      case label {
-        description
-          "The Label ERO subobject";
-        container label-hop {
-          description
-            "Label hop type";
-          uses effective-freq-slot;
-        }
-      }
-      case hop-attribute {
-        uses gnpypc:hop-attribute;
-      }
-    }
-  }
-
-  grouping common-constraints_config {
-    description
-      "Common constraints grouping that can be set on
-       a constraint set or directly on the tunnel";
-    container te-bandwidth {
-      description
-        "A requested bandwidth to use for path computation";
-      uses gnpy-specific-parameters;
-    }
-  }
-
-  grouping end-points {
-    description
-      "Common grouping to define the TE tunnel end-points";
-    leaf source {
-      type inet:ip-address;
-      description
-        "TE tunnel source address.";
-    }
-    leaf destination {
-      type inet:ip-address;
-      description
-        "P2P tunnel destination address";
-    }
-    leaf src-tp-id {
-      type binary;
-      description
-        "TE tunnel source termination point identifier.";
-    }
-    leaf dst-tp-id {
-      type binary;
-      description
-        "TE tunnel destination termination point
-         identifier.";
-    }
-  }
-
-  grouping synchronization-info {
-    description
-      "Information for sync";
-    list synchronization {
-      key "synchronization-id";
-      description
-        "sync list";
-      leaf synchronization-id {
-        type uint32;
-        description
-          "index";
-      }
-      container svec {
-        description
-          "Synchronization VECtor";
-        leaf relaxable {
-          type boolean;
-          default "true";
-          description
-            "If this leaf is true, path computation process is free
-             to ignore svec content.
-             otherwise it must take into account this svec.";
-        }
-        uses generic-path-disjointness;
-        leaf-list request-id-number {
-          type uint32;
-          description
-            "This list reports the set of M path computation requests that must be synchronized.";
-        }
-      }
-    }
-  }
-
-  grouping generic-path-properties {
-    description
-      "TE generic path properties grouping";
-    container path-properties {
-      config false;
-      description
-        "The TE path properties";
-      list path-metric {
-        key "metric-type";
-        description
-          "TE path metric type";
-        leaf metric-type {
-          type identityref {
-            base path-metric-type;
-          }
-          description
-            "TE path metric type";
-        }
-        leaf accumulative-value {
-          type decimal64 {
-            fraction-digits 2;
-          }
-          description
-            "TE path metric accumulative value";
-        }
-      }
-      //      container path-route-objects {
-      //        description
-      //          "Container for the list of route objects either returned by
-      //           the computation engine or actually used by an LSP";
-      //        list path-route-object {
-      //          key index;
-      //          description
-      //            "List of route objects either returned by the computation
-      //             engine or actually used by an LSP";
-      //          uses explicit-route-hop;
-      //        }
-      //      }
-      list path-route-objects {
-        description
-          "Container for the list of route objects either returned by
-           the computation engine or actually used by an LSP";
-        container path-route-object {
-          description
-            "List of route objects either returned by the computation
-             engine or actually used by an LSP";
-          uses explicit-route-hop;
-        }
-      }
-    }
-  }
-
-  grouping path-info {
-    description
-      "Path computation output information";
-    uses generic-path-properties;
-  }
-
-  // adding some blocking reasons and info on path in case of blocking
-
-  grouping no-path-info {
-    description
-      "no-path-info";
-    container no-path {
-      presence "Response without path information, due to failure
-                performing the path computation";
-      description
-        "if path computation cannot identify a path,
-         rpc returns no path.";
-      leaf no-path {
-        type string;
-        mandatory true;
-        description
-          "returned blocking reasons:
-            NO_PATH
-            NO_COMPUTED_SNR
-            NO_FEASIBLE_BAUDRATE_WITH_SPACING
-            NO_PATH_WITH_CONSTRAINT
-            NO_FEASIBLE_MODE
-            MODE_NOT_FEASIBLE
-            NO_SPECTRUM
-          ";
-      }
-      uses generic-path-properties;
-    }
-  }
-
-  /* TODO : correct the following with good trees:
-   *  te:tunnels-rpc/te:input/te:tunnel-info
-   *  te:tunnels-rpc/te:output/te:result
-   */
-
-  grouping service {
-    list path-request {
-      key "request-id";
-      description
-        "request-list";
-      leaf request-id {
-        type uint32;
-        mandatory true;
-        description
-          "Each path computation request is uniquely identified by the request-id-number.";
-      }
-      leaf bidirectional {
-        type boolean;
-        mandatory true;
-        description
-          "Specify the bidirectionality of the path";
-      }
-      uses end-points;
-      uses path-route-objects;
-      uses generic-path-constraints;
-    }
-    uses synchronization-info;
-  }
-
-  grouping result {
-    list response {
-      key "response-id";
-      config false;
-      description
-        "response";
-      leaf response-id {
-        type uint32;
-        description
-          "The list key that has to reuse request-id-number.";
-      }
-      choice response-type {
-        config false;
-        description
-          "response-type";
-        case no-path-case {
-          uses no-path-info;
-        }
-        case path-case {
-          description
-            "Path computation service.";
-          uses path-info;
-        }
-      }
-    }
-  }
-
-  container result {
-    description
-      "Describe the service file to connect to gnpy";
-    uses result;
-  }
-}
diff --git a/api/src/main/yang/gnpy-path-computation-simplified@2022-02-21.yang b/api/src/main/yang/gnpy-path-computation-simplified@2022-02-21.yang
new file mode 100644 (file)
index 0000000..24f2337
--- /dev/null
@@ -0,0 +1,612 @@
+module gnpy-path-computation-simplified {
+  yang-version 1.1;
+  namespace "gnpy:path";
+
+  prefix "gnpypc";
+
+    organization
+    "Telecom Infra Project OOPT PSE Working Group";
+
+  contact
+    "WG Web:   <https://github.com/Telecominfraproject/oopt-gnpy>
+     contact:  <mailto:ahmed.triki@orange.com>
+     contact:  <mailto:esther.lerouzic@orange.com>
+   ";
+
+  description
+    "YANG model for gnpy path computation simplified -
+    The license used for all the yang files of GNPy is BSD 3-Clause License
+
+    BSD 3-Clause License
+
+    Copyright (c) 2018, Telecom Infra Project
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    * Neither the name of the copyright holder nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2022-02-21 {
+    description
+      "draft for GNPy4TPCE preversion - non official version relevant for v2.4 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
+  revision 2020-10-22 {
+    description
+      "draft for experimental/2020-candi";
+    reference
+      "YANG model for path computation with gnpy inputs";
+  }
+
+  revision 2019-01-03 {
+    description
+      "first draft for GNPy4TPCE preversion - non official version relevant for v1.2 GNPy file format";
+    reference
+      "YANG model for api input for path computation with gnpy";
+  }
+
+  grouping effective-freq-slot{
+         /* content copied from ietf-flexi-grid-media-channel, because only M and N are needed
+            from the initial grouping.
+         */
+         description "The effective frequency slot is an attribute
+            of a media channel and, being a frequency slot, it is
+            described by its nominal central frequency and slot
+            width";
+         reference "rfc7698";
+            leaf N {
+              type int32;
+              description
+                  "Is used to determine the Nominal Central
+                  Frequency. The set of nominal central frequencies
+                  can be built using the following expression:
+                     f = 193.1 THz + n x 0.00625 THz,
+                  where 193.1 THz is ITU-T ''anchor frequency'' for
+                  transmission over the C band, n is a positive or
+                  negative integer including 0.";
+               reference "rfc7698";
+            }
+            leaf M {
+              type uint32;
+              description
+                  "Is used to determine the slot width. A slot width
+                  is constrained to be M x SWG (that is, M x 12.5 GHz),
+                  where M is an integer greater than or equal to 1.";
+               reference "rfc7698";
+    }
+  }
+
+  grouping gnpy-specific-parameters{
+    description
+      "This grouping defines the gnpy specific parameters for requests.";
+        leaf technology {
+            type string;
+            default "flexi-grid";
+            description
+          "Data plane technology type.";
+          }
+      leaf trx_type {
+        type string ;
+        mandatory true;
+        description "name of the transponder type (to be read from equipment library";
+
+      }
+      leaf trx_mode {
+        type string;
+        description "name of the transponder mode (to be read from equipment library";
+
+      }
+      list effective-freq-slot {
+        key "N";
+        uses effective-freq-slot ;
+      }
+      leaf spacing {
+        mandatory true;
+        type decimal64 {
+          fraction-digits 1;
+        }
+        units Hz;
+        description
+          "It is the spacing between channels assuming full load with
+          same channels as the requested one. multiple of 12.5 GHz";
+
+      }
+      leaf max-nb-of-channel{
+        type int32;
+        description "Nb of channel to take into account for the full load case.
+        ";
+
+      }
+      leaf output-power{
+        type decimal64 {
+          fraction-digits 5;
+        }
+        units W;
+        description "optical power setting to be used for the propagation";
+
+      }
+      leaf path_bandwidth{
+        type decimal64 {
+          fraction-digits 5;
+        }
+        mandatory true;
+        units bit/s;
+        description "Capacity required";
+      }
+  }
+
+  identity SNR-bandwidth {
+    base path-metric-type;
+    description
+      "A metric that records SNR in signal bandwidth";
+  }
+
+  identity OSNR-bandwidth {
+    base path-metric-type;
+    description
+      "A metric that records OSNR in signal bandwidth";
+  }
+
+  identity SNR-0.1nm {
+    base path-metric-type;
+    description
+      "A metric that records SNR in 0.1nm";
+  }
+
+  identity OSNR-0.1nm {
+    base path-metric-type;
+    description
+      "A metric that records OSNR in 0.1nm";
+  }
+
+  identity reference_power {
+    base path-metric-type;
+    description
+      "to be revised";
+  }
+
+  identity path_bandwidth {
+     base path-metric-type;
+     description
+       "to be revised";
+  }
+
+  grouping transponder{
+        leaf transponder-type {
+        type string ;
+        description
+          "transponder type.";
+          }
+      leaf transponder-mode {
+        type string ;
+        description
+          "transponder mode.";
+          }
+  }
+
+  grouping hop-attribute{
+    description
+      "This grouping defines the hop attribute parameters for request or response";
+    choice hop-type{
+      case tsp {
+        container transponder{
+          uses transponder ;
+        }
+      }
+      case regen {
+        container regenerator{
+          leaf regenerator-id{
+            type string ;
+          }
+          uses transponder ;
+        }
+      }
+      case pow {
+        container optical-power{
+          leaf optical-power{
+            type decimal64 {
+              fraction-digits 5;
+            }
+            units W;
+            description "not used yet. hop output (input??) power";
+          }
+        }
+      }
+    }
+
+  }
+
+  identity path-metric-type {
+    description
+      "Base identity for path metric type";
+  }
+
+  identity route-usage-type {
+    description
+      "Base identity for route usage";
+  }
+
+  identity route-include-ero {
+    base route-usage-type;
+    description
+      "Include ERO from route";
+  }
+
+  identity route-exclude-ero {
+    base route-usage-type;
+    description
+      "Exclude ERO from route";
+  }
+
+  identity route-exclude-srlg {
+    base route-usage-type;
+    description
+      "Exclude SRLG from route";
+  }
+
+  typedef te-hop-type {
+    type enumeration {
+      enum LOOSE {
+        description
+          "loose hop in an explicit path";
+      }
+      enum STRICT {
+        description
+          "strict hop in an explicit path";
+      }
+    }
+    description
+     "enumerated type for specifying loose or strict
+      paths";
+    reference "RFC3209: section-4.3.2";
+  }
+
+  typedef te-path-disjointness {
+    type bits {
+      bit node {
+        position 0;
+        description "Node disjoint.";
+      }
+      bit link {
+        position 1;
+        description "Link disjoint.";
+      }
+      bit srlg {
+        position 2;
+        description "SRLG (Shared Risk Link Group) disjoint.";
+      }
+    }
+    description
+      "Type of the resource disjointness for a TE tunnel path.";
+    reference
+      "RFC4872: RSVP-TE Extensions in Support of End-to-End
+       Generalized Multi-Protocol Label Switching (GMPLS)
+       Recovery";
+  } // te-path-disjointness
+
+    typedef accumulated-metric-type {
+      type union {
+        type uint64;
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      description
+          "type useable for accumulative-value";
+  }
+
+  grouping path-route-objects {
+    description
+      "List of EROs to be included or excluded when performing
+       the path computation.";
+    container explicit-route-objects {
+      description
+        "Container for the route object list";
+      list route-object-include-exclude {
+        description
+          "List of explicit route objects to include or
+           exclude in path computation";
+        leaf explicit-route-usage {
+          type identityref {
+            base route-usage-type;
+          }
+          description "Explicit-route usage.";
+        }
+        key "index";
+        uses explicit-route-hop ;
+      }
+    }
+  }
+
+  grouping generic-path-disjointness {
+    description "Path disjointness grouping";
+    leaf disjointness {
+      type te-path-disjointness;
+      description
+        "The type of resource disjointness.
+         Under primary path, disjointness level applies to
+         all secondary LSPs. Under secondary, disjointness
+         level overrides the one under primary";
+    }
+  }
+
+  grouping common-path-constraints-attributes {
+    description
+      "Common path constraints configuration grouping";
+    uses common-constraints_config;
+  }
+
+  grouping generic-path-constraints {
+    description
+      "Global named path constraints configuration
+      grouping";
+    container path-constraints {
+      description "TE named path constraints container";
+      uses common-path-constraints-attributes;
+    }
+  }
+
+
+  grouping explicit-route-hop {
+    description
+      "The explicit route subobject grouping";
+    leaf index {
+      type uint32;
+      description "ERO subobject index";
+    }
+    choice type {
+      description
+        "The explicit route subobject type";
+      case num-unnum-hop {
+        container num-unnum-hop {
+          leaf node-id {
+            //type te-node-id;
+            type string;
+            description
+              "The identifier of a node in the TE topology.";
+          }
+          leaf link-tp-id {
+            //type te-tp-id;
+            type string;
+            description
+              "TE link termination point identifier. The combination
+              of TE link ID and the TE node ID is used to identify an
+              unnumbered TE link.";
+          }
+          leaf hop-type {
+            type te-hop-type;
+            description "strict or loose hop";
+          }
+          description
+            "Numbered and Unnumbered link/node explicit route
+            subobject";
+        }
+      }
+      case label {
+        container label-hop {
+          description "Label hop type";
+          uses effective-freq-slot;
+        }
+        description
+          "The Label ERO subobject";
+      }
+      case hop-attribute{
+        uses gnpypc:hop-attribute ;
+      }
+    }
+  }
+
+  grouping common-constraints_config {
+    description
+      "Common constraints grouping that can be set on
+       a constraint set or directly on the tunnel";
+
+    container te-bandwidth {
+      uses gnpy-specific-parameters ;
+      description
+        "A requested bandwidth to use for path computation";
+    }
+  }
+
+  grouping end-points {
+    description
+      "Common grouping to define the TE tunnel end-points";
+
+    leaf source {
+      type string;
+      description "TE tunnel source address.";
+    }
+    leaf destination {
+      type string;
+      description "P2P tunnel destination address";
+    }
+    leaf src-tp-id {
+      type string;
+      description "TE tunnel source termination point identifier.";
+    }
+    leaf dst-tp-id {
+      type string;
+      description "TE tunnel destination termination point
+    identifier.";
+    }
+  }
+
+  grouping synchronization-info {
+    description "Information for sync";
+    list synchronization {
+      key "synchronization-id";
+      description "sync list";
+      leaf synchronization-id {
+        type string;
+        description "index";
+      }
+      container svec {
+        description
+         "Synchronization VECtor";
+        leaf relaxable {
+          type boolean;
+          default true;
+          description
+            "If this leaf is true, path computation process is free
+            to ignore svec content.
+            otherwise it must take into account this svec.";
+        }
+        uses generic-path-disjointness;
+        leaf-list request-id-number {
+          type string;
+          description "This list reports the set of M path computation requests that must be synchronized.";
+        }
+      }
+    }
+  }
+
+  grouping path-metric {
+    description "TE path metric type";
+    leaf metric-type {
+      type identityref {
+        base path-metric-type;
+      }
+      description "TE path metric type";
+    }
+    leaf accumulative-value {
+      type decimal64 {
+          fraction-digits 2;
+      }
+      description "TE path metric accumulative value";
+    }
+  }
+  grouping generic-path-properties {
+    description "TE generic path properties grouping";
+    container path-properties {
+      config false;
+      description "The TE path properties";
+      list path-metric {
+        key metric-type;
+        uses path-metric;
+      }
+      list z-a-path-metric {
+        key metric-type;
+        uses path-metric;
+      }
+      list path-route-objects {
+          description
+            "Container for the list of route objects either returned by
+             the computation engine or actually used by an LSP";
+          container path-route-object {
+            description
+              "List of route objects either returned by the computation
+               engine or actually used by an LSP";
+            uses explicit-route-hop;
+          }
+        }
+    }
+  }
+
+  grouping path-info {
+    uses generic-path-properties;
+    description "Path computation output information";
+  }
+
+// adding some blocking reasons and info on path in case of blocking
+
+  grouping no-path-info {
+    description "no-path-info";
+    container no-path {
+      presence "Response without path information, due to failure
+        performing the path computation";
+      leaf no-path {
+        type string;
+        mandatory true ;
+        description
+          "returned blocking reasons:
+            NO_PATH
+            NO_COMPUTED_SNR
+            NO_FEASIBLE_BAUDRATE_WITH_SPACING
+            NO_PATH_WITH_CONSTRAINT
+            NO_FEASIBLE_MODE
+            MODE_NOT_FEASIBLE
+            NO_SPECTRUM
+          ";
+        }
+      uses generic-path-properties ;
+      description "if path computation cannot identify a path,
+        rpc returns no path.";
+    }
+  }
+
+   grouping service {
+     list path-request {
+       key "request-id";
+       description "request-list";
+       leaf request-id {
+         type string;
+         mandatory true;
+         description "Each path computation request is uniquely identified by the request-id-number.";
+       }
+       leaf bidirectional {
+         type boolean;
+         mandatory true;
+         description "Specify the bidirectionality of the path";
+       }
+
+       uses end-points;
+       uses path-route-objects;
+       uses generic-path-constraints;
+     }
+     uses synchronization-info;
+   }
+
+   grouping result {
+     list response {
+       key response-id;
+       config false;
+       description "response";
+       leaf response-id {
+         type string;
+         description
+         "The list key that has to reuse request-id-number.";
+       }
+       choice response-type {
+         config false;
+         description "response-type";
+         case no-path-case {
+           uses no-path-info;
+         }
+         case path-case {
+           uses path-info;
+           description "Path computation service.";
+         }
+       }
+     }
+   }
+
+
+  container result {
+    uses gnpypc:result;
+    description
+      "Describe the response object to gnpy";
+  }
+}
index efb8fb7172062f8335bf13a619a8ab0afaf5fac7..cc626e1218b5685244dd1e8c795e7e314061d2b0 100644 (file)
@@ -33,6 +33,9 @@ public final class GridConstant {
     public static final double CENTRAL_FREQUENCY = 193.1;
     public static final int NB_SLOTS_100G = 8;
     public static final int NB_SLOTS_400G = 14;
+    public static final double OUTPUT_POWER_100GB_DBM = 2;
+    public static final BigDecimal OUTPUT_POWER_100GB_W = BigDecimal.valueOf(0.0015849);
+    public static final BigDecimal OUTPUT_POWER_400GB_W =  BigDecimal.valueOf(0.0027735);
     public static final BigDecimal WIDTH_80 = BigDecimal.valueOf(80);
     public static final BigDecimal WIDTH_75 = BigDecimal.valueOf(75);
     public static final BigDecimal WIDTH_40 = BigDecimal.valueOf(40);
@@ -89,7 +92,7 @@ public final class GridConstant {
     public static final Map<Uint32, Integer> RATE_SPECTRAL_WIDTH_SLOT_NUMBER_MAP = Map.of(
             ServiceRateConstant.RATE_100, NB_SLOTS_100G,
             ServiceRateConstant.RATE_200, NB_SLOTS_100G,
-            ServiceRateConstant.RATE_300, NB_SLOTS_100G,
+            ServiceRateConstant.RATE_300, NB_SLOTS_400G,
             ServiceRateConstant.RATE_400, NB_SLOTS_400G);
 
     private GridConstant() {
@@ -107,6 +110,7 @@ public final class GridConstant {
     private static Table<Uint32, ModulationFormat, BigDecimal> initFrequencySlotWidthTable() {
         Table<Uint32, ModulationFormat, BigDecimal> frequencyWidthTable = HashBasedTable.create();
         frequencyWidthTable.put(ServiceRateConstant.RATE_100, ModulationFormat.DpQpsk, SLOT_WIDTH_50);
+        frequencyWidthTable.put(ServiceRateConstant.RATE_200, ModulationFormat.DpQam16, SLOT_WIDTH_50);
         frequencyWidthTable.put(ServiceRateConstant.RATE_200, ModulationFormat.DpQpsk, SLOT_WIDTH_87_5);
         frequencyWidthTable.put(ServiceRateConstant.RATE_300, ModulationFormat.DpQam8, SLOT_WIDTH_87_5);
         frequencyWidthTable.put(ServiceRateConstant.RATE_400, ModulationFormat.DpQam16, SLOT_WIDTH_87_5);
index a38897eaac8e851e90998f285d88a7e380068f6e..efbe2034ba4c97c4efbecbefbea19b5af7c03431 100644 (file)
@@ -221,4 +221,13 @@ public final class GridUtils {
         return frequencyIndex - 284;
     }
 
+    /**
+     * Convert the power from dBm to Watt.
+     * @param  dbm power in dBm.
+     * @return outputpower in Watt.
+     */
+    public static BigDecimal convertDbmW(double dbm) {
+        return BigDecimal.valueOf(Math.pow(10, (dbm - 30) / 10));
+    }
+
 }
index eeb972371b90642371bf845340c8ba067f68c638..2085e96cdcaa002f29276c08eb64353ecaa1cfa1 100644 (file)
@@ -21,7 +21,7 @@ import org.junit.Test;
 import org.opendaylight.transportpce.test.AbstractTest;
 import org.opendaylight.transportpce.test.converter.DataObjectConverter;
 import org.opendaylight.transportpce.test.converter.JSONDataObjectConverter;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -36,12 +36,12 @@ public class JsonStringConverterTest extends AbstractTest {
         try (Reader reader = new FileReader("src/test/resources/gnpy_request.json", StandardCharsets.UTF_8)) {
             NormalizedNode normalizedNode = dataObjectConverter
                     .transformIntoNormalizedNode(reader).get();
-            GnpyApi gnpyRequest = (GnpyApi) getDataStoreContextUtil().getBindingDOMCodecServices()
-                    .fromNormalizedNode(YangInstanceIdentifier.of(GnpyApi.QNAME), normalizedNode).getValue();
-            JsonStringConverter<GnpyApi> gnpyJsonCOnverter = new JsonStringConverter<GnpyApi>(
+            Request gnpyRequest = (Request) getDataStoreContextUtil().getBindingDOMCodecServices()
+                    .fromNormalizedNode(YangInstanceIdentifier.of(Request.QNAME), normalizedNode).getValue();
+            JsonStringConverter<Request> gnpyJsonConverter = new JsonStringConverter<Request>(
                     getDataStoreContextUtil().getBindingDOMCodecServices());
-            String jsonString = gnpyJsonCOnverter
-                    .createJsonStringFromDataObject(InstanceIdentifier.builder(GnpyApi.class).build(),
+            String jsonString = gnpyJsonConverter
+                    .createJsonStringFromDataObject(InstanceIdentifier.builder(Request.class).build(),
                             gnpyRequest, JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
             assertEquals("Should be a valid request",
                     Files.readString(Paths.get("src/test/resources/expected_string.json")), jsonString);
@@ -53,10 +53,10 @@ public class JsonStringConverterTest extends AbstractTest {
     @Test
     public void createDataObjectFromJsonStringTest() throws IOException {
         String json = Files.readString(Paths.get("src/test/resources/expected_string.json"));
-        JsonStringConverter<GnpyApi> gnpyJsonCOnverter = new JsonStringConverter<GnpyApi>(
+        JsonStringConverter<Request> gnpyJsonCOnverter = new JsonStringConverter<Request>(
                 getDataStoreContextUtil().getBindingDOMCodecServices());
-        GnpyApi request = gnpyJsonCOnverter
-                .createDataObjectFromJsonString(YangInstanceIdentifier.of(GnpyApi.QNAME), json,
+        Request request = gnpyJsonCOnverter
+                .createDataObjectFromJsonString(YangInstanceIdentifier.of(Request.QNAME), json,
                         JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
         assertNotNull("Should not be null", request);
     }
index 12a2760ab7828af6453040b10186955a39d4d8ce..73dcdfbdbda4ee97601a1c8c4ec313f80bfe5990 100644 (file)
@@ -1 +1 @@
-{"gnpy-api":{"service-file":{"path-request":[{"request-id":2,"src-tp-id":"c3JjVHBJZA\u003d\u003d","destination":"127.0.0.41","explicit-route-objects":{"route-object-include-exclude":[{"explicit-route-usage":"gnpy-path-computation-simplified:route-include-ero","num-unnum-hop":{"hop-type":"STRICT","link-tp-id":"1","node-id":"127.0.0.20"},"index":0},{"explicit-route-usage":"gnpy-path-computation-simplified:route-include-ero","num-unnum-hop":{"hop-type":"STRICT","link-tp-id":"1","node-id":"127.0.0.30"},"index":1}]},"bidirectional":false,"dst-tp-id":"ZHN0VHBJZA\u003d\u003d","path-constraints":{"te-bandwidth":{"technology":"flexi-grid","trx_mode":"W100G","spacing":50000000000,"trx_type":"openroadm-beta1","path_bandwidth":100,"effective-freq-slot":[{"N":0,"M":4}]}},"source":"127.0.0.11"}]},"topology-file":{"elements":[{"uid":"243.0.0.10","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.12,"att_in":0,"con_out":0,"con_in":0,"length":60,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.11","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.12,"att_in":0,"con_out":0,"con_in":0,"length":60,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.12","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.29,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.13","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.2127659574468085124099303584443987347185611724853515625,"att_in":0,"con_out":0,"con_in":0,"length":140,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.14","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.29,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"127.0.0.20","type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20},"metadata":{"location":{"region":"OpenROADM-2","latitude":0,"longitude":0}}},{"uid":"127.0.0.41","type":"gnpy-network-topology:Transceiver","metadata":{"location":{"region":"XPONDER-4","latitude":0,"longitude":0}}},{"uid":"127.0.0.40","type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20},"metadata":{"location":{"region":"OpenROADM-4","latitude":0,"longitude":0}}},{"uid":"127.0.0.21","type":"gnpy-network-topology:Transceiver","metadata":{"location":{"region":"XPONDER-2","latitude":0,"longitude":0}}},{"uid":"243.0.0.1","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.11999999999999999555910790149937383830547332763671875,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.3","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.12,"att_in":0,"con_out":0,"con_in":0,"length":60,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.2","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.29,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.5","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.12,"att_in":0,"con_out":0,"con_in":0,"length":60,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.4","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.29,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.7","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.29,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.6","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.2127659574468085124099303584443987347185611724853515625,"att_in":0,"con_out":0,"con_in":0,"length":140,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.9","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.29,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"243.0.0.8","type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"loss_coef":0.11999999999999999555910790149937383830547332763671875,"att_in":0,"con_out":0,"con_in":0,"length":100,"length_units":"gnpy-network-topology:km"},"metadata":{"location":{"city":"N/A","region":"N/A","latitude":0,"longitude":0}}},{"uid":"127.0.0.31","type":"gnpy-network-topology:Transceiver","metadata":{"location":{"region":"XPONDER-3","latitude":0,"longitude":0}}},{"uid":"127.0.0.30","type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20},"metadata":{"location":{"region":"OpenROADM-3","latitude":0,"longitude":0}}},{"uid":"127.0.0.51","type":"gnpy-network-topology:Transceiver","metadata":{"location":{"region":"XPONDER-5","latitude":0,"longitude":0}}},{"uid":"127.0.0.50","type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20},"metadata":{"location":{"region":"OpenROADM-5","latitude":0,"longitude":0}}},{"uid":"127.0.0.11","type":"gnpy-network-topology:Transceiver","metadata":{"location":{"region":"XPONDER-1","latitude":0,"longitude":0}}},{"uid":"127.0.0.10","type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20},"metadata":{"location":{"region":"OpenROADM-1","latitude":0,"longitude":0}}}],"connections":[{"from_node":"127.0.0.51","to_node":"127.0.0.50"},{"from_node":"127.0.0.30","to_node":"127.0.0.31"},{"from_node":"127.0.0.10","to_node":"243.0.0.1"},{"from_node":"243.0.0.1","to_node":"127.0.0.30"},{"from_node":"127.0.0.20","to_node":"127.0.0.21"},{"from_node":"127.0.0.20","to_node":"243.0.0.2"},{"from_node":"243.0.0.2","to_node":"127.0.0.10"},{"from_node":"127.0.0.20","to_node":"243.0.0.3"},{"from_node":"243.0.0.3","to_node":"127.0.0.50"},{"from_node":"127.0.0.40","to_node":"127.0.0.41"},{"from_node":"127.0.0.40","to_node":"243.0.0.4"},{"from_node":"243.0.0.4","to_node":"127.0.0.30"},{"from_node":"127.0.0.50","to_node":"243.0.0.5"},{"from_node":"243.0.0.5","to_node":"127.0.0.30"},{"from_node":"127.0.0.31","to_node":"127.0.0.30"},{"from_node":"127.0.0.50","to_node":"127.0.0.51"},{"from_node":"127.0.0.20","to_node":"243.0.0.6"},{"from_node":"243.0.0.6","to_node":"127.0.0.30"},{"from_node":"127.0.0.30","to_node":"243.0.0.7"},{"from_node":"243.0.0.7","to_node":"127.0.0.40"},{"from_node":"127.0.0.11","to_node":"127.0.0.10"},{"from_node":"127.0.0.30","to_node":"243.0.0.8"},{"from_node":"243.0.0.8","to_node":"127.0.0.10"},{"from_node":"127.0.0.40","to_node":"243.0.0.9"},{"from_node":"243.0.0.9","to_node":"127.0.0.50"},{"from_node":"127.0.0.30","to_node":"243.0.0.10"},{"from_node":"243.0.0.10","to_node":"127.0.0.50"},{"from_node":"127.0.0.50","to_node":"243.0.0.11"},{"from_node":"243.0.0.11","to_node":"127.0.0.20"},{"from_node":"127.0.0.50","to_node":"243.0.0.12"},{"from_node":"243.0.0.12","to_node":"127.0.0.40"},{"from_node":"127.0.0.21","to_node":"127.0.0.20"},{"from_node":"127.0.0.41","to_node":"127.0.0.40"},{"from_node":"127.0.0.30","to_node":"243.0.0.13"},{"from_node":"243.0.0.13","to_node":"127.0.0.20"},{"from_node":"127.0.0.10","to_node":"127.0.0.11"},{"from_node":"127.0.0.10","to_node":"243.0.0.14"},{"from_node":"243.0.0.14","to_node":"127.0.0.20"}]}}}
\ No newline at end of file
+{"request":{"topology":{"connections":[{"from_node":"127.0.0.51","to_node":"127.0.0.50"},{"from_node":"127.0.0.30","to_node":"127.0.0.31"},{"from_node":"127.0.0.10","to_node":"243.0.0.1"},{"from_node":"243.0.0.1","to_node":"127.0.0.30"},{"from_node":"127.0.0.20","to_node":"127.0.0.21"},{"from_node":"127.0.0.20","to_node":"243.0.0.2"},{"from_node":"243.0.0.2","to_node":"127.0.0.10"},{"from_node":"127.0.0.20","to_node":"243.0.0.3"},{"from_node":"243.0.0.3","to_node":"127.0.0.50"},{"from_node":"127.0.0.40","to_node":"127.0.0.41"},{"from_node":"127.0.0.40","to_node":"243.0.0.4"},{"from_node":"243.0.0.4","to_node":"127.0.0.30"},{"from_node":"127.0.0.50","to_node":"243.0.0.5"},{"from_node":"243.0.0.5","to_node":"127.0.0.30"},{"from_node":"127.0.0.31","to_node":"127.0.0.30"},{"from_node":"127.0.0.50","to_node":"127.0.0.51"},{"from_node":"127.0.0.20","to_node":"243.0.0.6"},{"from_node":"243.0.0.6","to_node":"127.0.0.30"},{"from_node":"127.0.0.30","to_node":"243.0.0.7"},{"from_node":"243.0.0.7","to_node":"127.0.0.40"},{"from_node":"127.0.0.11","to_node":"127.0.0.10"},{"from_node":"127.0.0.30","to_node":"243.0.0.8"},{"from_node":"243.0.0.8","to_node":"127.0.0.10"},{"from_node":"127.0.0.40","to_node":"243.0.0.9"},{"from_node":"243.0.0.9","to_node":"127.0.0.50"},{"from_node":"127.0.0.30","to_node":"243.0.0.10"},{"from_node":"243.0.0.10","to_node":"127.0.0.50"},{"from_node":"127.0.0.50","to_node":"243.0.0.11"},{"from_node":"243.0.0.11","to_node":"127.0.0.20"},{"from_node":"127.0.0.50","to_node":"243.0.0.12"},{"from_node":"243.0.0.12","to_node":"127.0.0.40"},{"from_node":"127.0.0.21","to_node":"127.0.0.20"},{"from_node":"127.0.0.41","to_node":"127.0.0.40"},{"from_node":"127.0.0.30","to_node":"243.0.0.13"},{"from_node":"243.0.0.13","to_node":"127.0.0.20"},{"from_node":"127.0.0.10","to_node":"127.0.0.11"},{"from_node":"127.0.0.10","to_node":"243.0.0.14"},{"from_node":"243.0.0.14","to_node":"127.0.0.20"}],"elements":[{"uid":"127.0.0.11","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-1"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.10","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-1"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.51","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-5"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.50","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-5"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.31","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-3"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.30","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-3"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.21","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-2"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.40","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-4"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.20","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-2"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.41","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-4"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"243.0.0.12","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.29}},{"uid":"243.0.0.11","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":60,"con_out":0,"loss_coef":0.12}},{"uid":"243.0.0.10","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":60,"con_out":0,"loss_coef":0.12}},{"uid":"243.0.0.14","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.29}},{"uid":"243.0.0.13","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":140,"con_out":0,"loss_coef":0.2127659574468085124099303584443987347185611724853515625}},{"uid":"243.0.0.8","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.11999999999999999555910790149937383830547332763671875}},{"uid":"243.0.0.9","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.29}},{"uid":"243.0.0.4","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.29}},{"uid":"243.0.0.5","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":60,"con_out":0,"loss_coef":0.12}},{"uid":"243.0.0.6","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":140,"con_out":0,"loss_coef":0.2127659574468085124099303584443987347185611724853515625}},{"uid":"243.0.0.7","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.29}},{"uid":"243.0.0.1","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.11999999999999999555910790149937383830547332763671875}},{"uid":"243.0.0.2","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":100,"con_out":0,"loss_coef":0.29}},{"uid":"243.0.0.3","metadata":{"location":{"latitude":0,"city":"N/A","longitude":0,"region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"length_units":"gnpy-network-topology:km","att_in":0,"con_in":0,"length":60,"con_out":0,"loss_coef":0.12}}]},"service":{"path-request":[{"request-id":"2","bidirectional":false,"dst-tp-id":"ZHN0VHBJZA\u003d\u003d","src-tp-id":"c3JjVHBJZA\u003d\u003d","path-constraints":{"te-bandwidth":{"spacing":50000000000,"trx_mode":"W100G","trx_type":"openroadm-beta1","effective-freq-slot":[{"N":0,"M":4}],"path_bandwidth":100,"technology":"flexi-grid"}},"source":"127.0.0.11","explicit-route-objects":{"route-object-include-exclude":[{"index":0,"num-unnum-hop":{"hop-type":"STRICT","link-tp-id":"1","node-id":"127.0.0.20"},"explicit-route-usage":"gnpy-path-computation-simplified:route-include-ero"},{"index":1,"num-unnum-hop":{"hop-type":"STRICT","link-tp-id":"1","node-id":"127.0.0.30"},"explicit-route-usage":"gnpy-path-computation-simplified:route-include-ero"}]},"destination":"127.0.0.41"}]}}}
\ No newline at end of file
index 0219eef29bc8843a89f677430cf1b972bcfcd7ef..272f6990a6c81ed3fcba3779c78008a1405fef39 100644 (file)
@@ -1,6 +1,6 @@
 {
-  "gnpy-api": {
-    "topology-file": {
+  "request": {
+    "topology": {
       "elements": [
         {
           "uid": "127.0.0.40",
         }
       ]
     },
-    "service-file": {
+    "service": {
       "path-request": [
         {
           "request-id": 2,
index 36faf86e0f5c852171ce31e85e408b8bd4694356..59cd3a02eafe5050df1b70eabc44466312b65a23 100644 (file)
@@ -11,19 +11,15 @@ package org.opendaylight.transportpce.pce.gnpy;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 import java.util.stream.Collectors;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.NumUnnumHop;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetric;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.Response;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.NoPathCase;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCase;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.explicit.route.hop.type.NumUnnumHop;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.path.properties.PathMetric;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.path.properties.PathRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.Response;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type.NoPathCase;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type.PathCase;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.General;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.GeneralBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Include;
@@ -35,8 +31,6 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.NodeBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraintsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,10 +46,10 @@ public class GnpyResult {
 
     private static final Logger LOG = LoggerFactory.getLogger(GnpyResult.class);
     private Response response = null;
-    private Map<String, IpAddress> mapNodeRefIp = new HashMap<>();
+    private List<String> ordNodeList = new ArrayList<>();
 
     public GnpyResult(Result result, GnpyTopoImpl gnpyTopo) throws GnpyException {
-        this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
+        this.ordNodeList = gnpyTopo.getElementsList();
         List<Response> responses = new ArrayList<>(result.nonnullResponse().values());
         if (responses.isEmpty()) {
             throw new GnpyException("In GnpyResult: the response from GNpy is null!");
@@ -124,26 +118,18 @@ public class GnpyResult {
         int counter = 0;
         for (PathRouteObjects pathRouteObjects : pathRouteObjectList) {
             if (pathRouteObjects.getPathRouteObject().getType() instanceof NumUnnumHop) {
-                NumUnnumHop numUnnumHop = (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type
-                    .NumUnnumHop) pathRouteObjects.getPathRouteObject().getType();
-                String nodeIp = numUnnumHop.getNumUnnumHop().getNodeId();
-                try {
-                    IpAddress nodeIpAddress = new IpAddress(new Ipv4Address(nodeIp));
-                    // find the corresponding node-id (in ord-ntw) corresponding to nodeId (in gnpy response)
-                    String nodeId = findOrdNetworkNodeId(nodeIpAddress);
-                    if (nodeId != null) {
-                        org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017
-                            .ordered.constraints.sp.hop.type.hop.type.Node node = new NodeBuilder().setNodeId(nodeId)
-                            .build();
-                        HopType hopType = new HopTypeBuilder().setHopType(node).build();
-                        OrderedHops orderedHops = new OrderedHopsBuilder()
-                                .setHopNumber(Uint16.valueOf(counter)).setHopType(hopType)
-                            .build();
-                        orderedHopsList.add(orderedHops);
-                        counter++;
-                    }
-                } catch (IllegalArgumentException e) {
-                    LOG.error(" in GnpyResult: the element {} is not a ipv4Address ", nodeIp, e);
+                NumUnnumHop numUnnumHop = (NumUnnumHop) pathRouteObjects.getPathRouteObject().getType();
+                String nodeId = numUnnumHop.getNumUnnumHop().getNodeId();
+                if (nodeId != null && this.ordNodeList.contains(nodeId)) {
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017
+                        .ordered.constraints.sp.hop.type.hop.type.Node node = new NodeBuilder().setNodeId(nodeId)
+                        .build();
+                    HopType hopType = new HopTypeBuilder().setHopType(node).build();
+                    OrderedHops orderedHops = new OrderedHopsBuilder()
+                            .setHopNumber(Uint16.valueOf(counter)).setHopType(hopType)
+                        .build();
+                    orderedHopsList.add(orderedHops);
+                    counter++;
                 }
             }
         }
@@ -156,17 +142,6 @@ public class GnpyResult {
         return hardConstraints;
     }
 
-    private String findOrdNetworkNodeId(IpAddress nodeIpAddress) {
-        Iterator<Map.Entry<String,IpAddress>> it = this.mapNodeRefIp.entrySet().iterator();
-        while (it.hasNext()) {
-            Entry<String, IpAddress> entry = it.next();
-            if (entry.getValue().equals(nodeIpAddress)) {
-                return entry.getKey();
-            }
-        }
-        return null;
-    }
-
     public Response getResponse() {
         return response;
     }
index 3a23036b7ad0dcedfae241590efc181ec3d2c4f6..102b324ea968b2f16351eb65b9bbb64791c6db7b 100644 (file)
@@ -8,12 +8,12 @@
 
 package org.opendaylight.transportpce.pce.gnpy;
 
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
 import java.math.BigDecimal;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -21,39 +21,39 @@ import java.util.Map;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.transportpce.common.ServiceRateConstant;
 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
 import org.opendaylight.transportpce.common.fixedflex.GridUtils;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
 import org.opendaylight.transportpce.pce.gnpy.utils.AToZComparator;
 import org.opendaylight.transportpce.pce.gnpy.utils.ZToAComparator;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.Elements;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.ElementsKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.RouteIncludeEro;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeHopType;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeNodeId;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TePathDisjointness;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeTpId;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.common.constraints_config.TeBandwidth;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.common.constraints_config.TeBandwidthBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.Type;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.NumUnnumHopBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.num.unnum.hop.NumUnnumHop;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.constraints.PathConstraints;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.constraints.PathConstraintsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.gnpy.specific.parameters.EffectiveFreqSlot;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.gnpy.specific.parameters.EffectiveFreqSlotBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.ExplicitRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.ExplicitRouteObjectsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.explicit.route.objects.RouteObjectIncludeExclude;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequestBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequestKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.Synchronization;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.SynchronizationBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.synchronization.Svec;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.synchronization.SvecBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.Elements;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.ElementsKey;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.RouteIncludeEro;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.TeHopType;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.TePathDisjointness;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.common.constraints_config.TeBandwidth;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.common.constraints_config.TeBandwidthBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.explicit.route.hop.Type;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.explicit.route.hop.type.NumUnnumHopBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.explicit.route.hop.type.num.unnum.hop.NumUnnumHop;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.constraints.PathConstraints;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.constraints.PathConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.gnpy.specific.parameters.EffectiveFreqSlot;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.gnpy.specific.parameters.EffectiveFreqSlotBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.path.route.objects.ExplicitRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.path.route.objects.ExplicitRouteObjectsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.path.route.objects.explicit.route.objects.RouteObjectIncludeExclude;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeKey;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.service.PathRequestBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.service.PathRequestKey;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.synchronization.info.Synchronization;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.synchronization.info.SynchronizationBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.synchronization.info.synchronization.Svec;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.synchronization.info.synchronization.SvecBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.PathComputationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.FrequencyTHz;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.ModulationFormat;
@@ -62,11 +62,11 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdes
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToA;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.Resource;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 /**
  * Class to create the service corresponding to GNPy requirements.
  *
@@ -76,21 +76,32 @@ import org.slf4j.LoggerFactory;
 
 public class GnpyServiceImpl {
     private static final Logger LOG = LoggerFactory.getLogger(GnpyServiceImpl.class);
-    private static final Comparator<RouteObjectIncludeExclude> ROUTE_OBJECT_COMPARATOR =
-            Comparator.comparing(RouteObjectIncludeExclude::getIndex);
 
     private Map<PathRequestKey, PathRequest> pathRequest = new HashMap<>();
     private List<Synchronization> synchronization = new ArrayList<>();
     private Map<String, String> mapDisgNodeRefNode = new HashMap<>();
-    private Map<String, IpAddress> mapNodeRefIp = new HashMap<>();
     private Map<String, List<String>> mapLinkFiber = new HashMap<>();
-    private Map<String, IpAddress> mapFiberIp = new HashMap<>();
     private List<String> trxList = new ArrayList<>();
     private Map<ElementsKey, Elements> elements = new HashMap<>();
-    private List<RouteObjectIncludeExclude> routeObjectIncludeExcludes = new ArrayList<>();
-    private IpAddress currentNodeIpAddress = null;
+    private Map<RouteObjectIncludeExcludeKey, RouteObjectIncludeExclude> routeObjectIncludeExcludes = new HashMap<>();
+    private String currentNodeId = null;
     private AToZComparator atoZComparator =  new AToZComparator();
     private ZToAComparator ztoAComparator =  new ZToAComparator();
+    private static final Table<Uint32, BigDecimal, String> TRX_MODE_TABLE = initTrxModeTable();
+
+    private static Table<Uint32, BigDecimal, String> initTrxModeTable() {
+        Table<Uint32, BigDecimal, String> trxModeTable = HashBasedTable.create();
+        trxModeTable.put(ServiceRateConstant.RATE_100, GridConstant.SLOT_WIDTH_50, "100 Gbit/s, 27.95 Gbaud, DP-QPSK");
+        trxModeTable.put(ServiceRateConstant.RATE_200, GridConstant.SLOT_WIDTH_50, "200 Gbit/s, 31.57 Gbaud, DP-16QAM");
+        trxModeTable.put(ServiceRateConstant.RATE_200, GridConstant.SLOT_WIDTH_87_5, "200 Gbit/s, DP-QPSK");
+        trxModeTable.put(ServiceRateConstant.RATE_300, GridConstant.SLOT_WIDTH_87_5, "300 Gbit/s, DP-8QAM");
+        trxModeTable.put(ServiceRateConstant.RATE_400, GridConstant.SLOT_WIDTH_87_5, "400 Gbit/s, DP-16QAM");
+        return trxModeTable;
+    }
+
+    public static final Map<Uint32, BigDecimal> RATE_OUTPUTPOWER = Map.of(
+            ServiceRateConstant.RATE_100, GridConstant.OUTPUT_POWER_100GB_W,
+            ServiceRateConstant.RATE_400, GridConstant.OUTPUT_POWER_400GB_W);
 
     /*
      * Construct the GnpyServiceImpl
@@ -99,9 +110,7 @@ public class GnpyServiceImpl {
                 GnpyTopoImpl gnpyTopo, PceConstraints pceHardConstraints) throws GnpyException {
         this.elements = gnpyTopo.getElements();
         this.mapDisgNodeRefNode = gnpyTopo.getMapDisgNodeRefNode();
-        this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
         this.mapLinkFiber = gnpyTopo.getMapLinkFiber();
-        this.mapFiberIp = gnpyTopo.getMapFiberIp();
         this.trxList = gnpyTopo.getTrxList();
         try {
             this.pathRequest = extractPathRequest(input, atoz, requestId.toJava(), pceHardConstraints);
@@ -115,9 +124,7 @@ public class GnpyServiceImpl {
                 GnpyTopoImpl gnpyTopo, PceConstraints pceHardConstraints) throws GnpyException {
         this.elements = gnpyTopo.getElements();
         this.mapDisgNodeRefNode = gnpyTopo.getMapDisgNodeRefNode();
-        this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
         this.mapLinkFiber = gnpyTopo.getMapLinkFiber();
-        this.mapFiberIp = gnpyTopo.getMapFiberIp();
         this.trxList = gnpyTopo.getTrxList();
         try {
             pathRequest = extractPathRequest(input, ztoa, requestId.toJava(), pceHardConstraints);
@@ -140,14 +147,13 @@ public class GnpyServiceImpl {
 
         // Create explicitRouteObjects
         List<AToZ> listAtoZ = new ArrayList<>(atoz.nonnullAToZ().values());
-        if (!listAtoZ.isEmpty()) {
+        if (listAtoZ.isEmpty()) {
+            extractHardConstraints(pceHardConstraints);
+        } else {
             Collections.sort(listAtoZ, atoZComparator);
             extractRouteObjectIcludeAtoZ(listAtoZ);
-        } else {
-            extractHardConstraints(pceHardConstraints);
         }
 
-        Collections.sort(routeObjectIncludeExcludes, ROUTE_OBJECT_COMPARATOR);
         ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
             .setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
         //Create Path Constraint
@@ -158,10 +164,11 @@ public class GnpyServiceImpl {
 
         // Create the path request
         Map<PathRequestKey, PathRequest> pathRequestMap = new HashMap<>();
-        PathRequest pathRequestEl = new PathRequestBuilder().setRequestId(Uint32.valueOf(requestId))
-            .setSource(this.mapNodeRefIp.get(sourceNode)).setDestination(this.mapNodeRefIp.get(destNode))
-            .setSrcTpId("srcTpId".getBytes(StandardCharsets.UTF_8))
-            .setDstTpId("dstTpId".getBytes(StandardCharsets.UTF_8))
+        PathRequest pathRequestEl = new PathRequestBuilder().setRequestId(requestId.toString())
+            .setSource(sourceNode)
+            .setDestination(destNode)
+            .setSrcTpId(sourceNode)
+            .setDstTpId(destNode)
             .setBidirectional(false).setPathConstraints(pathConstraints).setPathConstraints(pathConstraints)
             .setExplicitRouteObjects(explicitRouteObjects).build();
         pathRequestMap.put(pathRequestEl.key(),pathRequestEl);
@@ -180,13 +187,13 @@ public class GnpyServiceImpl {
         }
         // Create explicitRouteObjects
         @NonNull List<ZToA> listZtoA = new ArrayList<>(ztoa.nonnullZToA().values());
-        if (!listZtoA.isEmpty()) {
+        if (listZtoA.isEmpty()) {
+            extractHardConstraints(pceHardConstraints);
+        } else {
             Collections.sort(listZtoA, ztoAComparator);
             extractRouteObjectIcludeZtoA(listZtoA);
-        } else {
-            extractHardConstraints(pceHardConstraints);
         }
-        Collections.sort(routeObjectIncludeExcludes, ROUTE_OBJECT_COMPARATOR);
+
         ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
             .setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
         //Create Path Constraint
@@ -195,12 +202,13 @@ public class GnpyServiceImpl {
                 ztoa.getZToAMinFrequency(),
                 ztoa.getZToAMaxFrequency());
 
-        // Create the path request
+        //Create the path request
         Map<PathRequestKey, PathRequest> pathRequestMap = new HashMap<>();
-        PathRequest pathRequestEl = new PathRequestBuilder().setRequestId(Uint32.valueOf(requestId))
-            .setSource(this.mapNodeRefIp.get(sourceNode)).setDestination(this.mapNodeRefIp.get(destNode))
-            .setSrcTpId("srcTpId".getBytes(StandardCharsets.UTF_8))
-            .setDstTpId("dstTpId".getBytes(StandardCharsets.UTF_8))
+        PathRequest pathRequestEl = new PathRequestBuilder().setRequestId(requestId.toString())
+            .setSource(sourceNode)
+            .setDestination(destNode)
+            .setSrcTpId(sourceNode)
+            .setDstTpId(destNode)
             .setBidirectional(false).setPathConstraints(pathConstraints)
             .setExplicitRouteObjects(explicitRouteObjects).build();
         pathRequestMap.put(pathRequestEl.key(),pathRequestEl);
@@ -266,7 +274,7 @@ public class GnpyServiceImpl {
         }
     }
 
-    // Create the list of nodes to include
+    //Create the list of nodes to include
     private List<String> getListToInclude(PceConstraints pceHardConstraints) {
         List<String> listNodeToInclude = new ArrayList<>();
         if (pceHardConstraints != null) {
@@ -285,18 +293,14 @@ public class GnpyServiceImpl {
     //Add a node to the route object
     private Long addNodeToRouteObject(String nodeRef, Long index) throws GnpyException {
         Long idx = index;
-        IpAddress ipAddress = this.mapNodeRefIp.get(nodeRef);
-        if (ipAddress == null) {
-            throw new GnpyException(String.format("In gnpyServiceImpl : NodeRef %s does not exist", nodeRef));
-        }
-
         for (Elements element : this.elements.values()) {
-            if (element.getUid().equals(ipAddress.getIpv4Address().getValue())) {
-                if ((this.currentNodeIpAddress == null) || (!this.currentNodeIpAddress.equals(ipAddress))) {
-                    this.currentNodeIpAddress = ipAddress;
-                    RouteObjectIncludeExclude routeObjectIncludeExclude = addRouteObjectIncludeExclude(ipAddress,
+            if (element.getUid().equals(nodeRef)) {
+                if ((this.currentNodeId == null) || (!this.currentNodeId.equals(nodeRef))) {
+                    this.currentNodeId = nodeRef;
+                    RouteObjectIncludeExclude routeObjectIncludeExclude = addRouteObjectIncludeExclude(nodeRef,
                             Uint32.valueOf(1), idx);
-                    routeObjectIncludeExcludes.add(routeObjectIncludeExclude);
+                    RouteObjectIncludeExcludeKey key = new RouteObjectIncludeExcludeKey(Uint32.valueOf(idx));
+                    routeObjectIncludeExcludes.put(key, routeObjectIncludeExclude);
                     idx += 1;
                 }
                 return idx;
@@ -320,27 +324,21 @@ public class GnpyServiceImpl {
             throw new GnpyException(String.format("In gnpyServiceImpl addNodeRouteObject : no sublink in %s",linkId));
         }
         for (String subLink : listSubLink) {
-            IpAddress fiberIp = this.mapFiberIp.get(subLink);
-            if (fiberIp == null) {
-                throw new GnpyException(String.format("In gnpyServiceImpl addNodeRouteObject : fiberIp of %s is null",
-                    subLink));
-            }
             RouteObjectIncludeExclude routeObjectIncludeExclude =
-                addRouteObjectIncludeExclude(fiberIp, Uint32.valueOf(1),idx);
-            routeObjectIncludeExcludes.add(routeObjectIncludeExclude);
+                addRouteObjectIncludeExclude(subLink, Uint32.valueOf(1),idx);
+            RouteObjectIncludeExcludeKey key = new RouteObjectIncludeExcludeKey(Uint32.valueOf(idx));
+            routeObjectIncludeExcludes.put(key, routeObjectIncludeExclude);
             idx += 1;
         }
         return idx;
     }
 
     // Add routeObjectIncludeExclude
-    private RouteObjectIncludeExclude addRouteObjectIncludeExclude(IpAddress ipAddress, Uint32 teTpValue, Long index) {
-        TeNodeId teNodeId = new TeNodeId(ipAddress);
-        TeTpId teTpId = new TeTpId(teTpValue);
-        NumUnnumHop numUnnumHop = new org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.num
+    private RouteObjectIncludeExclude addRouteObjectIncludeExclude(String nodeId, Uint32 teTpValue, Long index) {
+        NumUnnumHop numUnnumHop = new org.opendaylight.yang.gen.v1.gnpy.path.rev220221.explicit.route.hop.type.num
             .unnum.hop.NumUnnumHopBuilder()
-                .setNodeId(teNodeId.getIpv4Address().getValue())
-                .setLinkTpId(teTpId.getUint32().toString())
+                .setNodeId(nodeId)
+                .setLinkTpId(teTpValue.toString())
                 .setHopType(TeHopType.STRICT).build();
         Type type1 = new NumUnnumHopBuilder().setNumUnnumHop(numUnnumHop).build();
         // Create routeObjectIncludeExclude element
@@ -357,26 +355,29 @@ public class GnpyServiceImpl {
         if (minFrequency != null && maxFrequency != null && modulationFormat != null) {
             LOG.info("Creating path constraints for rate {}, modulationFormat {}, min freq {}, max freq {}", rate,
                     modulationFormat, minFrequency, maxFrequency);
-            FrequencyTHz centralFrequency = GridUtils
-                    .getCentralFrequency(minFrequency.getValue(), maxFrequency.getValue());
-            int centralFrequencyBitSetIndex = GridUtils.getIndexFromFrequency(centralFrequency.getValue());
-            mvalue = GridConstant.RATE_SPECTRAL_WIDTH_SLOT_NUMBER_MAP.getOrDefault(Uint32.valueOf(rate),
-                    GridConstant.NB_SLOTS_100G);
-            nvalue = GridUtils.getNFromFrequencyIndex(centralFrequencyBitSetIndex);
             ModulationFormat mformat = ModulationFormat.DpQpsk;
             Optional<ModulationFormat> optionalModulationFormat = ModulationFormat.forName(modulationFormat);
             if (optionalModulationFormat.isPresent()) {
                 mformat = optionalModulationFormat.get();
             }
             spacing = GridConstant.FREQUENCY_SLOT_WIDTH_TABLE.get(Uint32.valueOf(rate), mformat);
-
+            FrequencyTHz centralFrequency = GridUtils
+                    .getCentralFrequency(minFrequency.getValue(), maxFrequency.getValue());
+            int centralFrequencyBitSetIndex = GridUtils.getIndexFromFrequency(centralFrequency.getValue());
+            mvalue = (int) Math.ceil(spacing.doubleValue() / (GridConstant.GRANULARITY));
+            nvalue = GridUtils.getNFromFrequencyIndex(centralFrequencyBitSetIndex);
         }
         LOG.info("Creating path constraints for rate {}, mvalue {}, nvalue {}, spacing {}", rate,
                 mvalue, nvalue, spacing);
-        EffectiveFreqSlot effectiveFreqSlot = new EffectiveFreqSlotBuilder().setM(mvalue / 2).setN(nvalue).build();
-        // TODO : TrxMode is today hardcoded to W100G.
-        TeBandwidth teBandwidth = new TeBandwidthBuilder().setPathBandwidth(BigDecimal.valueOf(rate))
-                .setTechnology("flexi-grid").setTrxType("openroadm-beta1").setTrxMode("W100G")
+        EffectiveFreqSlot effectiveFreqSlot = new EffectiveFreqSlotBuilder()
+                .setM(Uint32.valueOf(mvalue / 2)).setN(nvalue).build();
+
+        TeBandwidth teBandwidth = new TeBandwidthBuilder()
+                .setPathBandwidth(BigDecimal.valueOf(rate * 1e9))
+                .setTechnology("flexi-grid").setTrxType("OpenROADM MSA ver. 5.0")
+                .setTrxMode(TRX_MODE_TABLE.get(Uint32.valueOf(rate), spacing))
+                .setOutputPower(GridUtils.convertDbmW(GridConstant.OUTPUT_POWER_100GB_DBM
+                        + 10 * Math.log10(mvalue / (double)GridConstant.NB_SLOTS_100G)))
                 .setEffectiveFreqSlot(Map.of(effectiveFreqSlot.key(), effectiveFreqSlot))
                 .setSpacing(spacing.multiply(BigDecimal.valueOf(1e9))).build();
         return new PathConstraintsBuilder().setTeBandwidth(teBandwidth).build();
@@ -385,14 +386,15 @@ public class GnpyServiceImpl {
     //Create the synchronization
     private List<Synchronization> extractSynchronization(Uint32 requestId) {
         // Create RequestIdNumber
-        List<Uint32> requestIdNumber = new ArrayList<>();
-        requestIdNumber.add(requestId);
+        List<String> requestIdNumber = new ArrayList<>();
+        requestIdNumber.add(requestId.toString());
         // Create a synchronization
         Svec svec = new SvecBuilder().setRelaxable(true)
             .setDisjointness(new TePathDisjointness(true, true, false))
             .setRequestIdNumber(requestIdNumber).build();
         List<Synchronization> synchro = new ArrayList<>();
-        Synchronization synchronization1 = new SynchronizationBuilder().setSynchronizationId(Uint32.valueOf(0))
+        Synchronization synchronization1 = new SynchronizationBuilder()
+                .setSynchronizationId(Uint32.valueOf(0).toString())
                 .setSvec(svec).build();
         synchro.add(synchronization1);
         return (synchro);
index a50bfd4d0a2746cefc77f6b0275ed7c699de92b8..7fef96e0c4cdbadff8c489f792c8c457e7e6368a 100644 (file)
@@ -15,35 +15,34 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
-import java.util.regex.Pattern;
 import java.util.stream.IntStream;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.transportpce.common.NetworkUtils;
 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.Coordinate;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.Km;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.edfa.params.Operational;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.edfa.params.OperationalBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.Edfa;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.EdfaBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.FiberRoadmBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.Transceiver;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.TransceiverBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.fiberroadm.Params;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.fiberroadm.ParamsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.fiberroadm.params.fiberroadm.Fiber;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.fiberroadm.params.fiberroadm.FiberBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.fiberroadm.params.fiberroadm.Roadm;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.element.type.choice.element.type.fiberroadm.params.fiberroadm.RoadmBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.location.attributes.Location;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.location.attributes.LocationBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.Connections;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.ConnectionsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.Elements;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.ElementsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.ElementsKey;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.elements.Metadata;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.elements.MetadataBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.Coordinate;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.Km;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.edfa.params.Operational;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.edfa.params.OperationalBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.Edfa;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.EdfaBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.FiberRoadmBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.Transceiver;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.TransceiverBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.fiberroadm.Params;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.fiberroadm.ParamsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.fiberroadm.params.fiberroadmfused.Fiber;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.fiberroadm.params.fiberroadmfused.FiberBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.fiberroadm.params.fiberroadmfused.Roadm;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.element.type.choice.element.type.fiberroadm.params.fiberroadmfused.RoadmBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.location.attributes.Location;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.location.attributes.LocationBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.Connections;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.ConnectionsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.Elements;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.ElementsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.ElementsKey;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.elements.Metadata;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.elements.MetadataBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev200529.SpanAttributes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev200529.amplified.link.attributes.AmplifiedLink;
@@ -53,8 +52,6 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev200529.span.attri
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.rev200529.Node1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.link.OMSAttributes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmLinkType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
@@ -80,22 +77,14 @@ public class GnpyTopoImpl {
     //List of elements
     private Map<ElementsKey, Elements> elements = new HashMap<>();
     private List<Connections> connections = new ArrayList<>();
+    private List<String> elementsList = new ArrayList<>();
     //Mapping elements
     //Mapping between the ord-topo and ord-ntw node
     private Map<String, String> mapDisgNodeRefNode = new HashMap<>();
-    //Mapping between the ord-ntw and node ip
-    private Map<String, IpAddress> mapNodeRefIp = new HashMap<>();
     //Mapping between the ROADM-ROADM linkId/secElement and the linkId
     private Map<String, List<String>> mapLinkFiber = new HashMap<>();
-    //Mapping between the ROADM-ROADM linkId/secElement and ipAddress
-    private Map<String, IpAddress> mapFiberIp = new HashMap<>();
     //List of Xponders
     private List<String> trxList = new ArrayList<>();
-    //Initialize the 32 bit identifiers for the edfa and the fiber.
-    //These 32-bit identifiers are not ipv4 addresses (despite having ipv4Adresses format, dotted-decimal notation).
-    //They are imposed by the GNPy yang model to identify network elements and not used for any routing purposes.
-    private Ipv4Address edfaId;
-    private Ipv4Address fiberId;
     private static final double LATITUDE = 0;
     private static final double LONGITUTE = 0;
     private static final String REGION = "N/A";
@@ -108,10 +97,6 @@ public class GnpyTopoImpl {
      */
     public GnpyTopoImpl(final NetworkTransactionService networkTransactionService) throws GnpyException {
         this.networkTransactionService = networkTransactionService;
-        //32-bit identifier for the fiber. The dotted decimal notation has the format 243.x.x.x (0<=x<=255)
-        fiberId = new Ipv4Address("243.0.0.1");
-        //32-bit identifier for the edfa. The dotted decimal notation has the format 244.x.x.x (0<=x<=255)
-        edfaId = new Ipv4Address("244.0.0.1");
         try {
             extractTopo();
         } catch (NullPointerException e) {
@@ -120,8 +105,7 @@ public class GnpyTopoImpl {
     }
 
     /*
-     * extract the topology: all the elements have ipAddress as uid and maintain
-     * a mapping structure to map between the nodeId and the ipAddress (uid)
+     * extract the topology
      *
      */
     private void extractTopo() throws GnpyException {
@@ -164,7 +148,6 @@ public class GnpyTopoImpl {
         // Create the list of nodes
         Collection<Node> openRoadmNetNodeList = openRoadmNet.get().nonnullNode().values();
         Collection<Node> openRoadmTopoNodeList = openRoadmTopo.get().nonnullNode().values();
-        List<String> nodesList = new ArrayList<>();
 
         if (openRoadmTopoNodeList.isEmpty() || openRoadmNetNodeList.isEmpty()) {
             throw new GnpyException("In gnpyTopoImpl: no nodes in the openradm topology or openroadm network");
@@ -178,7 +161,6 @@ public class GnpyTopoImpl {
                 if (!supportingNode.getNetworkRef().getValue().equals("openroadm-network")) {
                     continue;
                 }
-                IpAddress ipAddress = null;
                 String nodeRef = supportingNode.getNodeRef().getValue();
                 if (nodeRef == null) {
                     throw new GnpyException("In gnpyTopoImpl: nodeRef is null");
@@ -193,12 +175,6 @@ public class GnpyTopoImpl {
                         openRoadmNetNode1 = openRoadmNetNode.augmentation(Node1.class);
                         commonNetworkNode1 = openRoadmNetNode.augmentation(org.opendaylight.yang.gen.v1
                             .http.org.openroadm.common.network.rev200529.Node1.class);
-                        ipAddress = openRoadmNetNode1.getIp();
-                        if (ipAddress == null) {
-                            throw new GnpyException(String.format(
-                                "In gnpyTopoImpl: ipAddress of node %s is null",nodeRef));
-                        }
-                        mapNodeRefIp.put(nodeRef, ipAddress);
                         break;
                     }
                 }
@@ -206,18 +182,18 @@ public class GnpyTopoImpl {
                     throw new GnpyException(String.format("In gnpyTopoImpl: the node type of %s is null",nodeRef));
                 }
                 if (commonNetworkNode1.getNodeType().getName().equals("ROADM")) {
-                    if (!nodesList.contains(nodeRef)) {
+                    if (!elementsList.contains(nodeRef)) {
                         Elements element = createElementsRoadm(LATITUDE, LONGITUTE, nodeRef,
-                                openRoadmNetNode1.getShelf(),TARGET_PCH_OUT_DB, ipAddress.getIpv4Address().getValue());
+                                openRoadmNetNode1.getShelf(),TARGET_PCH_OUT_DB, nodeRef);
                         this.elements.put(element.key(),element);
-                        nodesList.add(nodeRef);
+                        elementsList.add(nodeRef);
                     }
                 } else if (commonNetworkNode1.getNodeType().getName().equals("XPONDER")) {
-                    if (!nodesList.contains(nodeRef)) {
+                    if (!elementsList.contains(nodeRef)) {
                         Elements element = createElementsTransceiver(LATITUDE, LONGITUTE, nodeRef,
-                                openRoadmNetNode1.getShelf(),ipAddress.getIpv4Address().getValue());
+                                openRoadmNetNode1.getShelf(), nodeRef);
                         this.elements.put(element.key(),element);
-                        nodesList.add(nodeRef);
+                        elementsList.add(nodeRef);
                         trxList.add(nodeRef);
                     }
                 } else {
@@ -257,10 +233,8 @@ public class GnpyTopoImpl {
             }
 
             String srcId = mapDisgNodeRefNode.get(link.getSource().getSourceNode().getValue());
-            IpAddress srcIp = mapNodeRefIp.get(srcId);
             String linkId = link.getLinkId().getValue();
             String destId = null;
-            IpAddress destIp = null;
             if (linkType == OpenroadmLinkType.ROADMTOROADM.getIntValue()) {
                 OMSAttributes omsAttributes = openroadmNetworkLink1.getOMSAttributes();
                 if (omsAttributes == null) {
@@ -269,82 +243,76 @@ public class GnpyTopoImpl {
                 }
                 //Case of amplified link
                 if (omsAttributes.getAmplifiedLink() != null) {
-                    srcIp = extractAmplifiedLink(omsAttributes, linkId, srcIp);
+                    srcId = extractAmplifiedLink(omsAttributes, linkId, srcId);
                 }
                 //Case of one span link
                 if (omsAttributes.getSpan() != null) {
-                    srcIp = extractSpanLink(omsAttributes, linkId, srcIp);
+                    srcId = extractSpanLink(omsAttributes, linkId, srcId);
                 }
             }
             // Create a new link
             destId = mapDisgNodeRefNode.get(link.getDestination().getDestNode().getValue());
-            destIp = mapNodeRefIp.get(destId);
-            createNewConnection(srcIp,destIp);
+            createNewConnection(srcId,destId);
         }
     }
 
-    private IpAddress extractAmplifiedLink(OMSAttributes omsAttributes, String linkId, IpAddress srcIp)
+    private String extractAmplifiedLink(OMSAttributes omsAttributes, String linkId, String srcId)
         throws GnpyException {
 
         List<AmplifiedLink> amplifiedLinkList = new ArrayList<>(omsAttributes.getAmplifiedLink()
             .nonnullAmplifiedLink().values());
-        IpAddress destIp = null;
+        String destId = null;
         if (!amplifiedLinkList.isEmpty()) {
             for (AmplifiedLink amplifiedLink: amplifiedLinkList) {
                 String secElt = amplifiedLink .getSectionEltNumber().toString();
                 //Case of ILA
                 if (amplifiedLink.getSectionElement().getSectionElement() instanceof Ila) {
                     Ila ila = (Ila) amplifiedLink.getSectionElement().getSectionElement();
-                    destIp = extractILAFromAmpLink(ila);
+                    destId = extractILAFromAmpLink(ila);
                 }
                 //Case of Span
                 if (amplifiedLink.getSectionElement().getSectionElement() instanceof Span) {
                     Span span = (Span) amplifiedLink.getSectionElement().getSectionElement();
-                    destIp = extractSpan(span.getSpan(), linkId, secElt);
+                    destId = extractSpan(span.getSpan(), linkId, secElt);
                 }
                 // Create a new link
-                if (createNewConnection(srcIp,destIp)) {
-                    srcIp = destIp;
+                if (createNewConnection(srcId,destId)) {
+                    srcId = destId;
                 }
             }
         }
-        return srcIp;
+        return srcId;
     }
 
-    private IpAddress extractSpanLink(OMSAttributes omsAttributes, String linkId, IpAddress srcIp)
+    private String extractSpanLink(OMSAttributes omsAttributes, String linkId, String srcId)
         throws GnpyException {
 
         SpanAttributes span = omsAttributes.getSpan();
-        IpAddress destIp = extractSpan(span, linkId, linkId);
-        if (createNewConnection(srcIp, destIp)) {
-            return destIp;
+        String destId = extractSpan(span, linkId, linkId);
+        if (createNewConnection(srcId, destId)) {
+            return destId;
         }
-        return srcIp;
+        return srcId;
     }
 
-    private IpAddress extractILAFromAmpLink(Ila ila) throws GnpyException {
+    private String extractILAFromAmpLink(Ila ila) throws GnpyException {
         String nodeId = ila.getNodeId().getValue();
-        IpAddress ipEdfa = new IpAddress(edfaId);
-        edfaId = incrementIdentifier(edfaId);
         mapDisgNodeRefNode.put(nodeId, nodeId);
-        mapNodeRefIp.put(nodeId, ipEdfa);
         Elements element = createElementsEdfa(LATITUDE, LONGITUTE, REGION, CITY,
                 ila.getGain().getValue(), ila.getTilt().getValue(),
                 ila.getOutVoaAtt().getValue(), "std_medium_gain",
-                ipEdfa.getIpv4Address().getValue());
+                nodeId);
         this.elements.put(element.key(),element);
-        return ipEdfa;
+        return nodeId;
     }
 
-    private IpAddress extractSpan(SpanAttributes span, String linkId, String subLinkId) throws GnpyException {
-        IpAddress ipFiber = new IpAddress(fiberId);
-
+    private String extractSpan(SpanAttributes span, String linkId, String subLinkId) throws GnpyException {
         if (!mapLinkFiber.containsKey(linkId)) {
             mapLinkFiber.put(linkId, new ArrayList<>());
         }
         mapLinkFiber.get(linkId).add(subLinkId);
-        mapFiberIp.put(subLinkId, ipFiber);
-        fiberId = incrementIdentifier(fiberId);
+        //mapFiberIp.put(subLinkId, ipFiber);
+        //fiberId = incrementIdentifier(fiberId);
         double attIn = 0;
         double connIn = 0;
         double connOut = 0;
@@ -362,10 +330,9 @@ public class GnpyTopoImpl {
         }
         double lossCoef = span.getSpanlossCurrent().getValue().doubleValue() / length;
         Elements element = createElementsFiber(LATITUDE, LONGITUTE, REGION, CITY,
-            ipFiber.getIpv4Address().getValue(), length, attIn, lossCoef, connIn, connOut, typeVariety);
+                subLinkId, length, attIn, lossCoef, connIn, connOut, typeVariety);
         this.elements.put(element.key(),element);
-        return ipFiber;
-
+        return subLinkId;
     }
 
     /*
@@ -383,9 +350,9 @@ public class GnpyTopoImpl {
                 .setAttIn(BigDecimal.valueOf(attIn)).setLossCoef(BigDecimal.valueOf(lossCoef))
                 .setConIn(BigDecimal.valueOf(connIn))
                 .setConOut(BigDecimal.valueOf(connOut)).build();
-        Params params1 = new ParamsBuilder().setFiberroadm(fiber).build();
+        Params params1 = new ParamsBuilder().setFiberroadmfused(fiber).build();
         return new ElementsBuilder().setUid(uidFiber)
-                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.Fiber.class)
+                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.Fiber.class)
                 .setTypeVariety(typeVariety).setMetadata(metadata1)
                 .setElementType(new FiberRoadmBuilder().setParams(params1).build()).build();
     }
@@ -406,7 +373,7 @@ public class GnpyTopoImpl {
         Edfa edfa = new EdfaBuilder()
                 .setOperational(operational).build();
         return new ElementsBuilder().setUid(uidEdfa)
-                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.Edfa.class)
+                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.Edfa.class)
                 .setMetadata(metadata1).setElementType(edfa).setTypeVariety(typeVariety).build();
     }
 
@@ -422,9 +389,9 @@ public class GnpyTopoImpl {
                 .build();
         Metadata metadata1 = new MetadataBuilder().setLocation(location1).build();
         Roadm roadm = new RoadmBuilder().setTargetPchOutDb(BigDecimal.valueOf(targetPchOutDb)).build();
-        Params params1 = new ParamsBuilder().setFiberroadm(roadm).build();
+        Params params1 = new ParamsBuilder().setFiberroadmfused(roadm).build();
         return new ElementsBuilder().setUid(uidRoadm)
-                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.Roadm.class)
+                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.Roadm.class)
                 .setMetadata(metadata1).setElementType(new FiberRoadmBuilder().setParams(params1).build()).build();
     }
 
@@ -440,19 +407,17 @@ public class GnpyTopoImpl {
         Metadata metadata1 = new MetadataBuilder().setLocation(location1).build();
         Transceiver transceiver = new TransceiverBuilder().build();
         return new ElementsBuilder().setUid(uidTrans)
-                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.Transceiver.class)
+                .setType(org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.Transceiver.class)
                 .setMetadata(metadata1).setElementType(transceiver).build();
     }
 
     /*
      * Method to create Connection
      */
-    private boolean createNewConnection(IpAddress srcIp, IpAddress destIp) throws GnpyException {
-        if (srcIp == null || destIp == null) {
+    private boolean createNewConnection(String fromNode, String toNode) throws GnpyException {
+        if (fromNode == null || toNode == null) {
             throw new GnpyException("create new connection : null node IpAddress");
         }
-        String fromNode = srcIp.getIpv4Address().getValue();
-        String toNode = destIp.getIpv4Address().getValue();
         if (fromNode.equals(toNode)) {
             return false;
         }
@@ -461,38 +426,6 @@ public class GnpyTopoImpl {
         return true;
     }
 
-    /*
-     * Increment 32-bit identifier
-     */
-    private Ipv4Address incrementIdentifier(Ipv4Address id)  throws GnpyException {
-        String ips = id.getValue();
-        String [] fields = ips.split(Pattern.quote("."));
-        int intF1 = Integer.parseInt(fields[1]);
-        int intF2 = Integer.parseInt(fields[2]);
-        int intF3 = Integer.parseInt(fields[3]);
-        if (intF3 < 255) {
-            intF3++;
-        } else {
-            if (intF2 < 255) {
-                intF2++;
-                intF3 = 0;
-            } else {
-                if (intF1 < 255) {
-                    intF1++;
-                    intF2 = 0;
-                    intF3 = 0;
-                } else {
-                    throw new GnpyException("GnpyTopoImpl : the topology is not supported by gnpy");
-                }
-                fields[1] = Integer.toString(intF1);
-            }
-            fields[2] = Integer.toString(intF2);
-        }
-        fields[3] = Integer.toString(intF3);
-        String nidString = fields[0] + "." + fields[1] + "." + fields[2] + "." + fields[3];
-        return new Ipv4Address(nidString);
-    }
-
     public Map<ElementsKey, Elements> getElements() {
         return elements;
     }
@@ -509,20 +442,20 @@ public class GnpyTopoImpl {
         this.connections = connections;
     }
 
-    public Map<String, String> getMapDisgNodeRefNode() {
-        return mapDisgNodeRefNode;
+    public List<String> getElementsList() {
+        return elementsList;
     }
 
-    public void setMapDisgNodeRefNode(Map<String, String> mapDisgNodeRefNode) {
-        this.mapDisgNodeRefNode = mapDisgNodeRefNode;
+    public void setElementsList(List<String> elementsList) {
+        this.elementsList = elementsList;
     }
 
-    public Map<String, IpAddress> getMapNodeRefIp() {
-        return mapNodeRefIp;
+    public Map<String, String> getMapDisgNodeRefNode() {
+        return mapDisgNodeRefNode;
     }
 
-    public void setMapNodeRefIp(Map<String, IpAddress> mapNodeRefIp) {
-        this.mapNodeRefIp = mapNodeRefIp;
+    public void setMapDisgNodeRefNode(Map<String, String> mapDisgNodeRefNode) {
+        this.mapDisgNodeRefNode = mapDisgNodeRefNode;
     }
 
     public Map<String, List<String>> getMapLinkFiber() {
@@ -533,14 +466,6 @@ public class GnpyTopoImpl {
         this.mapLinkFiber = mapLinkFiber;
     }
 
-    public Map<String, IpAddress> getMapFiberIp() {
-        return mapFiberIp;
-    }
-
-    public void setMapFiberIp(Map<String, IpAddress> mapFiberIp) {
-        this.mapFiberIp = mapFiberIp;
-    }
-
     public List<String> getTrxList() {
         return trxList;
     }
index d50f970804f39679e8df45de098a3c3cfb611c45..97aae94c31016b080a622cd42ec771065f414f7b 100644 (file)
@@ -14,16 +14,15 @@ import java.util.stream.Collectors;
 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.transportpce.pce.gnpy.consumer.GnpyConsumer;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApiBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.ServiceFileBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.TopologyFileBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.Connections;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.Elements;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.Synchronization;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.RequestBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.request.ServiceBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.request.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.Connections;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev220221.topo.Elements;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.path.properties.PathRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.synchronization.info.Synchronization;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.PathComputationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirection;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirectionBuilder;
@@ -115,19 +114,19 @@ public class GnpyUtilitiesImpl {
     }
 
     public Result getGnpyResponse(List<Elements> elementsList, List<Connections> connectionsList,
-        List<PathRequest> pathRequestList, List<Synchronization> synchronizationList) {
-        GnpyApi gnpyApi = new GnpyApiBuilder()
-            .setTopologyFile(
-                new TopologyFileBuilder()
+            List<PathRequest> pathRequestList, List<Synchronization> synchronizationList) {
+
+        return gnpyConsumer.computePaths(new RequestBuilder()
+            .setTopology(
+                new TopologyBuilder()
                 .setElements(elementsList.stream().collect(Collectors.toMap(Elements::key, element -> element)))
                 .setConnections(connectionsList).build())
-            .setServiceFile(
-                new ServiceFileBuilder()
+            .setService(
+                new ServiceBuilder()
                 .setPathRequest(pathRequestList.stream()
                         .collect(Collectors.toMap(PathRequest::key, pathRequest -> pathRequest)))
                 .build())
-            .build();
-        return gnpyConsumer.computePaths(gnpyApi);
+            .build());
     }
 
     public GnpyResult getGnpyAtoZ() {
index 549b95deb972c5c8e317f9fbe391ae08b89724b7..f750005ccda96197a317ac13c927edf2cdfdf9fa 100644 (file)
@@ -10,8 +10,10 @@ package org.opendaylight.transportpce.pce.gnpy.consumer;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
 import org.opendaylight.transportpce.common.converter.JsonStringConverter;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
+
+
 
 //This class is a temporary workaround while waiting jackson
 //support in yang tools https://git.opendaylight.org/gerrit/c/yangtools/+/94852
@@ -19,10 +21,9 @@ public class GnpyApiModule extends SimpleModule {
 
     private static final long serialVersionUID = 1L;
 
-    public GnpyApiModule(JsonStringConverter<GnpyApi> gnpyApiConverter, JsonStringConverter<Result> resultConverter) {
+    public GnpyApiModule(JsonStringConverter<Request> requestConverter, JsonStringConverter<Result> resultConverter) {
         super(PackageVersion.VERSION);
-        addSerializer(GnpyApi.class, new GnpyApiSerializer(gnpyApiConverter));
+        addSerializer(Request.class, new RequestSerializer(requestConverter));
         addDeserializer(Result.class, new ResultDeserializer(resultConverter));
     }
-
 }
index 5c69347a1efa641651f6889ba4dc901faa8d89e4..b45a3880f3cb92af924993a06e160fcefce2eaef 100644 (file)
@@ -7,8 +7,10 @@
  */
 package org.opendaylight.transportpce.pce.gnpy.consumer;
 
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
+
 
 public interface GnpyConsumer {
 
@@ -23,6 +25,6 @@ public interface GnpyConsumer {
      * @param request GnpyApi.
      * @return Result the result of pat computation.
      */
-    Result computePaths(GnpyApi request);
+    Result computePaths(Request request);
 
 }
index 4913624a5b034c62dc806c242e3b7e4ad9f53f6f..cd4b6eb69913b9f7c070c8101772948ef6f504d8 100644 (file)
@@ -17,8 +17,8 @@ import org.glassfish.jersey.jackson.JacksonFeature;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
 import org.opendaylight.transportpce.common.converter.JsonStringConverter;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -26,14 +26,15 @@ public class GnpyConsumerImpl implements GnpyConsumer {
     private static final Logger LOG = LoggerFactory.getLogger(GnpyConsumerImpl.class);
 
     private GnpyResource api;
-    private JsonStringConverter<GnpyApi> gnpyApiConverter;
-    private JsonStringConverter<Result> resultConverter;
+    JsonStringConverter<Request> gnpyRequestConverter;
+    JsonStringConverter<Result> resultConverter;
 
     public GnpyConsumerImpl(String baseUrl, String username, String password,
             BindingDOMCodecServices bindingDOMCodecServices) {
-        gnpyApiConverter = new JsonStringConverter<>(bindingDOMCodecServices);
+        gnpyRequestConverter = new JsonStringConverter<>(bindingDOMCodecServices);
         resultConverter = new JsonStringConverter<>(bindingDOMCodecServices);
-        JsonConfigurator jsonConfigurator = new JsonConfigurator(gnpyApiConverter, resultConverter);
+
+        JsonConfigurator jsonConfigurator = new JsonConfigurator(gnpyRequestConverter, resultConverter);
         Client client = ClientBuilder.newClient();
         HttpAuthenticationFeature authFeature = HttpAuthenticationFeature.basic(username, password);
         client.register(authFeature);
@@ -45,7 +46,7 @@ public class GnpyConsumerImpl implements GnpyConsumer {
     @Override
     public boolean isAvailable() {
         try {
-            api.checkStatus();
+            api.getStatus();
             LOG.info("GNPy is available");
             return true;
         } catch (WebApplicationException | ProcessingException e) {
@@ -55,7 +56,7 @@ public class GnpyConsumerImpl implements GnpyConsumer {
     }
 
     @Override
-    public Result computePaths(GnpyApi request) {
+    public Result computePaths(Request request) {
         try {
             return api.computePathRequest(request);
         } catch (WebApplicationException | ProcessingException e) {
index 5b7377490859c20e4e826b31ba17fd78ca0fbcd1..a30112c8a5ba51173d95f074f612d6722304bf27 100644 (file)
@@ -8,23 +8,31 @@
 package org.opendaylight.transportpce.pce.gnpy.consumer;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
 import javax.ws.rs.HEAD;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
 
-@Path("/gnpy/api/v1.0/files")
+
+@Path("/api/v1")
 public interface GnpyResource {
 
     @HEAD
     String checkStatus();
 
     @POST
+    @Path("/path-computation")
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
-    Result computePathRequest(GnpyApi request);
+    Result computePathRequest(Request request);
+
+    @GET
+    @Path("/status")
+    @Produces(MediaType.APPLICATION_JSON)
+    GnpyStatus getStatus();
 
 }
diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyStatus.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyStatus.java
new file mode 100644 (file)
index 0000000..2c3ceb4
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright Â© 2022 Orange, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.transportpce.pce.gnpy.consumer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class GnpyStatus {
+
+    @JsonProperty("version")
+    private String version;
+
+    @JsonProperty("status")
+    private String status;
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+}
index 9e051d15dadfcb91b59bd6ddf4dcd727fac11413..9bc37329545076bff7e051f018360e404b9216fc 100644 (file)
@@ -13,21 +13,21 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import javax.ws.rs.ext.ContextResolver;
 import org.opendaylight.transportpce.common.converter.JsonStringConverter;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
 
 public class JsonConfigurator implements ContextResolver<ObjectMapper> {
 
     private final ObjectMapper mapper;
 
-    public JsonConfigurator(JsonStringConverter<GnpyApi> gnpyApiConverter,
+    public JsonConfigurator(JsonStringConverter<Request> requestConverter,
             JsonStringConverter<Result> resultConverter) {
         mapper = new ObjectMapper();
         mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
         mapper.enable(SerializationFeature.INDENT_OUTPUT);
         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        mapper.registerModule(new GnpyApiModule(gnpyApiConverter, resultConverter));
+        mapper.registerModule(new GnpyApiModule(requestConverter, resultConverter));
     }
 
     @Override
similarity index 63%
rename from pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/GnpyApiSerializer.java
rename to pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/consumer/RequestSerializer.java
index 29cd17c4e534e0987255e4566ed8cd8034a009e5..4dd687cc4f4f4b20353c60ebdd9e809a786c9d79 100644 (file)
@@ -12,7 +12,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
 import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 import java.io.IOException;
 import org.opendaylight.transportpce.common.converter.JsonStringConverter;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
 import org.slf4j.Logger;
@@ -21,26 +21,25 @@ import org.slf4j.LoggerFactory;
 //This class is a temporary workaround while waiting jackson
 //support in yang tools https://git.opendaylight.org/gerrit/c/yangtools/+/94852
 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "temporary class")
-public class GnpyApiSerializer extends StdSerializer<GnpyApi> {
+
+public class RequestSerializer extends StdSerializer<Request> {
     private static final long serialVersionUID = 1L;
-    private static final Logger LOG = LoggerFactory.getLogger(GnpyApiSerializer.class);
-    private JsonStringConverter<GnpyApi> converter;
-    private InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
+    private static final Logger LOG = LoggerFactory.getLogger(RequestSerializer.class);
+    private JsonStringConverter<Request> converter;
+    private InstanceIdentifier<Request> idRequest = InstanceIdentifier.builder(Request.class).build();
 
-    public GnpyApiSerializer(JsonStringConverter<GnpyApi> converter) {
-        super(GnpyApi.class);
+    public RequestSerializer(JsonStringConverter<Request> converter) {
+        super(Request.class);
         this.converter = converter;
     }
 
     @Override
-    public void serialize(GnpyApi value, JsonGenerator gen, SerializerProvider provider) throws IOException {
-        String requestStr = converter
-                .createJsonStringFromDataObject(idGnpyApi, value,
+    public void serialize(Request value, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        String requestStr = this.converter
+                .createJsonStringFromDataObject(this.idRequest, value,
                         JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
-        requestStr =  requestStr.replace("gnpy-eqpt-config:", "")
-                .replace("gnpy-path-computation-simplified:", "").replace("gnpy-network-topology:", "");
+        requestStr =  requestStr.replace("gnpy-network-topology:", "");
         LOG.info("Serialized request {}", requestStr);
         gen.writeRaw(requestStr);
     }
-
 }
index 222be701df7d5f0138bd152806b1c178f52cac5d..8ddbb417ea933d48fa6867be1eb6c204ffcb0d44 100644 (file)
@@ -12,33 +12,36 @@ import com.fasterxml.jackson.databind.DeserializationContext;
 import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
 import java.io.IOException;
 import org.opendaylight.transportpce.common.converter.JsonStringConverter;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 
 //This class is a temporary workaround while waiting jackson
 //support in yang tools https://git.opendaylight.org/gerrit/c/yangtools/+/94852
 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "temporary class")
 public class ResultDeserializer extends StdDeserializer<Result> {
 
+    private static final Logger LOG = LoggerFactory.getLogger(ResultDeserializer.class);
     private static final long serialVersionUID = 1L;
-    private  JsonStringConverter<Result> converter;
-    private  YangInstanceIdentifier yangId;
+    private JsonStringConverter<Result> converter;
+    private YangInstanceIdentifier yangId;
 
     public ResultDeserializer(JsonStringConverter<Result> converter) {
         super(Result.class);
         this.converter = converter;
-        QName pathQname = QName.create("gnpy:path", "2020-09-09", "result");
+        QName pathQname = Result.QNAME;
+        LOG.info("QName of the first result class {}", pathQname);
         yangId = YangInstanceIdentifier.of(pathQname);
     }
 
     @Override
     public Result deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
-        return converter
-                .createDataObjectFromJsonString(yangId,
-                        parser.readValueAsTree().toString(),
-                        JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
+        return converter.createDataObjectFromJsonString(yangId,parser.readValueAsTree().toString(),
+            JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
     }
 
 }
index 519f057f1dd4a2df7eff08363e1a040999d657d7..7b4b990743d57b880631807e8fa5e3b0ad7f4ef6 100644 (file)
@@ -24,7 +24,7 @@ import org.opendaylight.transportpce.pce.PceComplianceCheckResult;
 import org.opendaylight.transportpce.pce.PceSendingPceRPCs;
 import org.opendaylight.transportpce.pce.gnpy.GnpyResult;
 import org.opendaylight.transportpce.pce.gnpy.consumer.GnpyConsumer;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.Response;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.Response;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.CancelResourceReserveInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.CancelResourceReserveOutput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.CancelResourceReserveOutputBuilder;
@@ -239,26 +239,26 @@ public class PathComputationServiceImpl implements PathComputationService {
         ResponseType respType = null;
         boolean feasible = true;
         if (responseGnpy != null) {
-            if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result
+            if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result
                     .response.response.type.NoPathCase) {
                 LOG.info("GNPy : path is not feasible");
-                org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.NoPathCase
-                    noPathGnpy = (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type
+                org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type.NoPathCase
+                    noPathGnpy = (org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type
                     .NoPathCase) responseGnpy.getResponseType();
                 NoPathCase noPathCase = new NoPathCaseBuilder().setNoPath(noPathGnpy.getNoPath()).build();
                 respType = noPathCase;
                 feasible = false;
-            } else if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result
+            } else if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result
                     .response.response.type.PathCase) {
                 LOG.info("GNPy : path is feasible");
-                org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCase pathCase =
-                        (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCase)
+                org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type.PathCase pathCase =
+                        (org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type.PathCase)
                         responseGnpy.getResponseType();
-                List<org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties
+                List<org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.path.properties
                     .PathMetric> pathMetricList =
                     new ArrayList<>(pathCase.getPathProperties().getPathMetric().values());
                 List<PathMetric> gnpyPathMetricList = new ArrayList<>();
-                for (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetric
+                for (org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.path.properties.PathMetric
                         pathMetricGnpy : pathMetricList) {
                     PathMetric pathMetric = new PathMetricBuilder().setMetricType(pathMetricGnpy.getMetricType())
                             .setAccumulativeValue(pathMetricGnpy.getAccumulativeValue()).build();
index 074f8d459ce3279601cf061709998b1cacc6a9bb..c8fae69daab85751568e4a4a8c88e455a72e3ce2 100644 (file)
@@ -19,8 +19,8 @@ import org.glassfish.jersey.test.JerseyTest;
 import org.junit.Test;
 import org.opendaylight.transportpce.common.converter.JsonStringConverter;
 import org.opendaylight.transportpce.test.AbstractTest;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.Result;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
@@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
 
 public class GnpyConsumerTest extends JerseyTest {
     private static final Logger LOG = LoggerFactory.getLogger(GnpyConsumerTest.class);
-    private JsonStringConverter<GnpyApi> gnpyApiConverter;
+    private JsonStringConverter<Request> gnpyApiConverter;
 
     @Override
     protected Application configure() {
@@ -53,9 +53,9 @@ public class GnpyConsumerTest extends JerseyTest {
                 "mylogin",
                 "mypassword",
                 AbstractTest.getDataStoreContextUtil().getBindingDOMCodecServices());
-        QName pathQname = QName.create("gnpy:gnpy-api", "2019-01-03", "gnpy-api");
+        QName pathQname = Request.QNAME;
         YangInstanceIdentifier yangId = YangInstanceIdentifier.of(pathQname);
-        GnpyApi request = gnpyApiConverter
+        Request request = gnpyApiConverter
                 .createDataObjectFromJsonString(yangId,
                         Files.readString(Paths.get("src/test/resources/gnpy/gnpy_request.json")),
                         JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
index 43d6db88ac1cfceecb7b41eae88701f418b7da83..aa6e86065225bd283cc524629848c0ed5db4f704 100644 (file)
@@ -14,22 +14,24 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
 import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
 import javax.ws.rs.HEAD;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.opendaylight.transportpce.common.converter.JsonStringConverter;
 import org.opendaylight.transportpce.test.AbstractTest;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev220221.Request;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.service.PathRequest;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Path("/gnpy/api/v1.0/files")
+@Path("/api/v1")
 public class GnpyStub {
     private static final Logger LOG = LoggerFactory.getLogger(GnpyStub.class);
 
@@ -38,30 +40,43 @@ public class GnpyStub {
         return Response.ok().build();
     }
 
+    @GET
+    @Path("/status")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getStatus() {
+        try {
+            String response = Files.readString(Paths.get("src", "test", "resources", "gnpy", "gnpy_status.json"));
+            return Response.ok(response).build();
+        } catch (IOException e) {
+            LOG.error("Cannot manage request", e);
+            return Response.serverError().build();
+        }
+    }
+
     @POST
     @Produces({ "application/json" })
     @Consumes({ "application/json" })
+    @Path("/path-computation")
     public Response computePath(String request) {
         LOG.info("Received path request {}", request);
-        URI location = URI.create("http://127.0.0.1:9998/gnpy/api/v1.0/files");
+        URI location = URI.create("http://127.0.0.1:9998/api/v1/path-computation");
         // TODO: return different response based on body data
-        QName pathQname = QName.create("gnpy:gnpy-api", "2019-01-03", "gnpy-api");
+        QName pathQname = Request.QNAME;
         YangInstanceIdentifier yangId = YangInstanceIdentifier.of(pathQname);
-        JsonStringConverter<GnpyApi> converter = new JsonStringConverter<>(
+        JsonStringConverter<Request> converter = new JsonStringConverter<>(
                 AbstractTest.getDataStoreContextUtil().getBindingDOMCodecServices());
         try {
             String response = null;
             request = request.replace("Transceiver", "gnpy-network-topology:Transceiver")
                     .replace("Roadm", "gnpy-network-topology:Roadm")
                     .replace("Fiber", "gnpy-network-topology:Fiber")
-                    .replace("km", "gnpy-network-topology:km")
-                    .replace("route-include-ero", "gnpy-path-computation-simplified:route-include-ero");
-            GnpyApi data = converter.createDataObjectFromJsonString(yangId,
+                    .replace("km", "gnpy-network-topology:km");
+            Request data = converter.createDataObjectFromJsonString(yangId,
                     request, JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
             LOG.info("Converted request {}", data);
-            List<PathRequest> pathRequest = new ArrayList<>(data.getServiceFile().nonnullPathRequest().values());
+            List<PathRequest> pathRequest = new ArrayList<>(data.getService().nonnullPathRequest().values());
             // this condition is totally arbitrary and could be modified
-            if (!pathRequest.isEmpty() && "127.0.0.31".contentEquals(pathRequest.get(0).getSource().stringValue())) {
+            if (!pathRequest.isEmpty() && "XPONDER-3".contentEquals(pathRequest.get(0).getSource())) {
                 response = Files
                         .readString(Paths.get("src", "test", "resources", "gnpy", "gnpy_result_with_path.json"));
             } else {
index 2bea3e823900e65c7c0ec0b5df00709bd87f1896..c021fe29fd970576c95e71ceb1cf1a9157499532 100644 (file)
@@ -21,17 +21,16 @@ import org.opendaylight.transportpce.pce.gnpy.GnpyTopoImpl;
 import org.opendaylight.transportpce.pce.utils.PceTestData;
 import org.opendaylight.transportpce.test.AbstractTest;
 import org.opendaylight.transportpce.test.DataStoreContext;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.PathBandwidth;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.PathPropertiesBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetric;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetricBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.no.path.info.NoPathBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.Response;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.ResponseBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.ResponseKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.NoPathCaseBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCaseBuilder;
-import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.PathBandwidth;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.PathPropertiesBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.path.properties.PathMetric;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.generic.path.properties.path.properties.PathMetricBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.no.path.info.NoPathBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.Response;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.ResponseBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.ResponseKey;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type.NoPathCaseBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev220221.result.response.response.type.PathCaseBuilder;
 
 public class PathComputationServiceImplTest extends AbstractTest {
 
@@ -64,7 +63,7 @@ public class PathComputationServiceImplTest extends AbstractTest {
     @Test
     public void testPathComputationRequestNoPath() {
         Response response = new ResponseBuilder()
-                .withKey(new ResponseKey(Uint32.valueOf(1))).setResponseType(new NoPathCaseBuilder()
+                .withKey(new ResponseKey("responseId")).setResponseType(new NoPathCaseBuilder()
                 .setNoPath(new NoPathBuilder().setNoPath("no path").build()).build()).build();
 
         pathComputationServiceImpl.generateGnpyResponse(response,"path");
@@ -79,7 +78,7 @@ public class PathComputationServiceImplTest extends AbstractTest {
                 .setAccumulativeValue(new BigDecimal(21))
                 .setMetricType(PathBandwidth.class).build();
         Response response = new ResponseBuilder()
-                .withKey(new ResponseKey(Uint32.valueOf(1))).setResponseType(new PathCaseBuilder()
+                .withKey(new ResponseKey("responseId")).setResponseType(new PathCaseBuilder()
                 .setPathProperties(new PathPropertiesBuilder().setPathMetric(Map.of(pathMetric.key(),pathMetric))
                 .build()).build()).build();
 
index 0219eef29bc8843a89f677430cf1b972bcfcd7ef..25916095a738e6eb04179822e9c8cc05e98c7135 100644 (file)
@@ -1,6 +1,6 @@
 {
-  "gnpy-api": {
-    "topology-file": {
+    "request": {
+    "topology": {
       "elements": [
         {
           "uid": "127.0.0.40",
         }
       ]
     },
-    "service-file": {
+    "service": {
       "path-request": [
         {
           "request-id": 2,
index d0b58860da2f4d46b9e514ead7e4d37d395099c4..21983b2de9124736a28eb1550c243f7a5aad5de4 100644 (file)
@@ -8,7 +8,7 @@
                     "path-properties": {
                         "path-metric": [
                             {
-                                "metric-type": "SNR-bandwidth",
+                                "gnpy-path:metric-type": "SNR-bandwidth",
                                 "accumulative-value": 13.06
                             },
                             {
diff --git a/pce/src/test/resources/gnpy/gnpy_status.json b/pce/src/test/resources/gnpy/gnpy_status.json
new file mode 100644 (file)
index 0000000..5f32751
--- /dev/null
@@ -0,0 +1,4 @@
+{
+    "status": "ok",
+    "version": "v1"
+}
\ No newline at end of file
index 239f7bbbe769a277bd7b64fa035caaeb00594ec1..3029dcaccb24843c0e27ca6c65990a7de4b9d159 100644 (file)
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
-                            "engineered-spanloss": 30.2,
+                            "spanloss-current": 20,
+                            "engineered-spanloss": 20.2,
                             "auto-spanloss": true
                         }
                     },
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
-                            "engineered-spanloss": 30.2,
+                            "spanloss-current": 20,
+                            "engineered-spanloss": 20.2,
                             "auto-spanloss": true
                         }
                     },
                             "link-concatenation": [
                                 {
                                     "SRLG-Id": 0,
-                                    "SRLG-length": 140000,
+                                    "SRLG-length": 133000,
                                     "pmd": 0.5,
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
+                            "spanloss-current": 27.93,
                             "engineered-spanloss": 30.2,
                             "auto-spanloss": true
                         }
                             "link-concatenation": [
                                 {
                                     "SRLG-Id": 0,
-                                    "SRLG-length": 140000,
+                                    "SRLG-length": 133000,
                                     "pmd": 0.5,
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
+                            "spanloss-current": 27.93,
                             "engineered-spanloss": 30.2,
                             "auto-spanloss": true
                         }
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
-                            "engineered-spanloss": 30.2,
+                            "spanloss-current": 20,
+                            "engineered-spanloss": 20.2,
                             "auto-spanloss": true
                         }
                     },
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
-                            "engineered-spanloss": 30.2,
+                            "spanloss-current": 20,
+                            "engineered-spanloss": 20.2,
                             "auto-spanloss": true
                         }
                     },
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
-                            "engineered-spanloss": 30.2,
+                            "spanloss-current": 20,
+                            "engineered-spanloss": 20.2,
                             "auto-spanloss": true
                         }
                     },
                                     "fiber-type": "smf"
                                 }
                             ],
-                            "spanloss-current": 29,
-                            "engineered-spanloss": 30.2,
+                            "spanloss-current": 20,
+                            "engineered-spanloss": 20.2,
                             "auto-spanloss": true
                         }
                     },
index 21b9b42b39f1403d722d71400f2eed7562ca94fd..57e1296204cd5133984575bbf89d1c01ea8d3104 100644 (file)
@@ -74,7 +74,7 @@ class TransportGNPYtesting(unittest.TestCase):
             print('starting GNPy REST server...')
             # pylint: disable=consider-using-with
             test_utils.process_list.append(subprocess.Popen(
-                ['path_requests_run.py', '--rest'], stdout=outfile, stderr=outfile, stdin=None))
+                ['gnpy-rest'], stdout=outfile, stderr=outfile, stdin=None))
         cls.processes = test_utils.start_tpce()
 
     @classmethod
@@ -196,15 +196,14 @@ class TransportGNPYtesting(unittest.TestCase):
     # Not found path by PCE and GNPy cannot find another one
     def test_07_path_computation_FoundByPCE_NotFeasibleByGnpy(self):
         response = test_utils.path_computation_request("request-4", "service-4",
-                                                       {"node-id": "XPONDER-1", "service-rate": "100",
+                                                       {"node-id": "XPONDER-1", "service-rate": "400",
                                                            "service-format": "Ethernet", "clli": "Node1"},
-                                                       {"node-id": "XPONDER-4", "service-rate": "100",
-                                                           "service-format": "Ethernet", "clli": "Node5"},
+                                                       {"node-id": "XPONDER-4", "service-rate": "400",
+                                                           "service-format": "Ethernet", "clli": "Node4"},
                                                        {"include_": {"ordered-hops": [
-                                                           {"hop-number": "0", "hop-type": {"node-id": "OpenROADM-2"}},
-                                                           {"hop-number": "1", "hop-type": {"node-id": "OpenROADM-3"}},
-                                                           {"hop-number": "2", "hop-type": {"node-id": "OpenROADM-4"}},
-                                                           {"hop-number": "3", "hop-type": {"node-id": "OpenROADM-3"}}]}
+                                                           {"hop-number": "0", "hop-type": {"node-id": "OpenROADM-3"}},
+                                                           {"hop-number": "1", "hop-type": {"node-id": "OpenROADM-2"}},
+                                                           {"hop-number": "2", "hop-type": {"node-id": "OpenROADM-5"}}]}
                                                         })
         self.assertEqual(response.status_code, requests.codes.ok)
         res = response.json()
diff --git a/tox.ini b/tox.ini
index 059b847c7d26cd91c9f39bdcf7e446850cb19a33..76c6b76ccb68424c3f8e7ae362a9d521a09f2b0d 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -64,9 +64,10 @@ deps =
   -r{toxinidir}/tests/requirements.txt
   -r{toxinidir}/tests/test-requirements.txt
   setuptools>=7.0
-  gnpy4tpce==1.2.1
+  gnpy4tpce==2.4.2
 whitelist_externals = launch_tests.sh
 passenv = LAUNCHER USE_LIGHTY USE_ODL_RESTCONF_VERSION
+basepython = python3.8
 #setenv =
 #    USE_LIGHTY=True
 commands =