+++ /dev/null
-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;
- }
- }
-}
--- /dev/null
+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
+++ /dev/null
-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;
-}
--- /dev/null
+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";
+ }
+ }
+ }
+ }
+}
+
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";
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";
identity Fiber {
base type-element;
description
- "Fiber element";
+ "Fiber element (unidirectional)";
}
identity Roadm {
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 {
}
}
- 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;
fraction-digits 2;
}
mandatory true;
+ units db/km;
+ description "Loss coefficient of the fiber span (dB/km)";
}
leaf length_units {
type identityref {
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;
}
}
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;
}
description
"..";
}
- leaf out-voa {
+ leaf out_voa {
type decimal64 {
fraction-digits 2;
}
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";
+ }
}
}
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 {
}
case FiberRoadm {
container params {
- choice fiberroadm {
+ choice fiberroadmfused {
case Fiber {
when "type = 'Fiber'";
uses fiber-params;
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";
config false;
leaf from_node {
type leafref {
- path ../../elements/uid;
+ path "../../elements/uid";
}
}
leaf to_node {
type leafref {
- path ../../elements/uid;
+ path "../../elements/uid";
}
}
}
+++ /dev/null
-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;
- }
-}
--- /dev/null
+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";
+ }
+}
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);
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() {
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);
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));
+ }
+
}
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;
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);
@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);
}
-{"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
{
- "gnpy-api": {
- "topology-file": {
+ "request": {
+ "topology": {
"elements": [
{
"uid": "127.0.0.40",
}
]
},
- "service-file": {
+ "service": {
"path-request": [
{
"request-id": 2,
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;
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;
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!");
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++;
}
}
}
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;
}
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;
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;
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.
*
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
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);
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);
// 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
// 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);
}
// 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
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);
}
}
- // 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) {
//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;
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
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();
//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);
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;
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;
//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";
*/
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) {
}
/*
- * 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 {
// 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");
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");
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;
}
}
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 {
}
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) {
}
//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;
}
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;
}
/*
.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();
}
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();
}
.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();
}
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;
}
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;
}
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() {
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;
}
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;
}
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() {
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
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));
}
-
}
*/
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 {
* @param request GnpyApi.
* @return Result the result of pat computation.
*/
- Result computePaths(GnpyApi request);
+ Result computePaths(Request request);
}
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;
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);
@Override
public boolean isAvailable() {
try {
- api.checkStatus();
+ api.getStatus();
LOG.info("GNPy is available");
return true;
} catch (WebApplicationException | ProcessingException e) {
}
@Override
- public Result computePaths(GnpyApi request) {
+ public Result computePaths(Request request) {
try {
return api.computePathRequest(request);
} catch (WebApplicationException | ProcessingException e) {
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();
}
--- /dev/null
+/*
+ * 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;
+ }
+}
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
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;
//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);
}
-
}
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);
}
}
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;
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();
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;
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() {
"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);
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);
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 {
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 {
@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");
.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();
{
- "gnpy-api": {
- "topology-file": {
+ "request": {
+ "topology": {
"elements": [
{
"uid": "127.0.0.40",
}
]
},
- "service-file": {
+ "service": {
"path-request": [
{
"request-id": 2,
"path-properties": {
"path-metric": [
{
- "metric-type": "SNR-bandwidth",
+ "gnpy-path:metric-type": "SNR-bandwidth",
"accumulative-value": 13.06
},
{
--- /dev/null
+{
+ "status": "ok",
+ "version": "v1"
+}
\ No newline at end of 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
}
},
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
# 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()
-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 =