mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-01 02:28:05 +00:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99f44a597b | ||
|
|
a21f3fe6ee | ||
|
|
0ccbb2960c | ||
|
|
87cc3dac00 | ||
|
|
89e28cc7be | ||
|
|
2ba29a78c5 | ||
|
|
f990a6c1be | ||
|
|
424e5a4786 | ||
|
|
6a7a04ebb1 | ||
|
|
0366fc2956 | ||
|
|
48b7d71f02 | ||
|
|
715baf2a1c | ||
|
|
e55cea776e | ||
|
|
b388d143fd | ||
|
|
c592c572d8 | ||
|
|
dfa0a26a28 | ||
|
|
609cd94798 | ||
|
|
022f743db1 | ||
|
|
1957beb1b6 | ||
|
|
9ca72d6105 | ||
|
|
e8e126a6ce | ||
|
|
7849782173 | ||
|
|
149a0da8c9 | ||
|
|
1e7c70a59b | ||
|
|
c9d8282e7f | ||
|
|
e7084a2c29 | ||
|
|
d79d2e0724 | ||
|
|
402155c225 | ||
|
|
e5ec669419 | ||
|
|
8f424e8c9d | ||
|
|
fea2b84bb9 | ||
|
|
0c918940c4 | ||
|
|
a63a6ac0ec | ||
|
|
9f58b914d2 | ||
|
|
029bac4b03 | ||
|
|
a27ad57220 | ||
|
|
8d31d924f2 | ||
|
|
8c3b514f90 | ||
|
|
3df27fe315 | ||
|
|
a6087ce354 | ||
|
|
aae0382523 |
@@ -7,7 +7,7 @@
|
|||||||
`gnpy`: mesh optical network route planning and optimization library
|
`gnpy`: mesh optical network route planning and optimization library
|
||||||
====================================================================
|
====================================================================
|
||||||
|
|
||||||
|docs| |build|
|
|docs| |build| |doi|
|
||||||
|
|
||||||
**`gnpy` is an open-source, community-developed library for building route
|
**`gnpy` is an open-source, community-developed library for building route
|
||||||
planning and optimization tools in real-world mesh optical networks.**
|
planning and optimization tools in real-world mesh optical networks.**
|
||||||
@@ -601,6 +601,11 @@ implementations.
|
|||||||
:alt: Build Status
|
:alt: Build Status
|
||||||
:scale: 100%
|
:scale: 100%
|
||||||
|
|
||||||
|
.. |doi| image:: https://zenodo.org/badge/96894149.svg
|
||||||
|
:target: https://zenodo.org/badge/latestdoi/96894149
|
||||||
|
:alt: DOI
|
||||||
|
:scale: 100%
|
||||||
|
|
||||||
TIP OOPT/PSE & PSE WG Charter
|
TIP OOPT/PSE & PSE WG Charter
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"path-request": [
|
"path-request": [
|
||||||
{
|
{
|
||||||
"request-id": "0",
|
"request-id": "0",
|
||||||
"source": "Lorient_KMA",
|
"source": "trx Lorient_KMA",
|
||||||
"destination": "Vannes_KBE",
|
"destination": "trx Vannes_KBE",
|
||||||
"src-tp-id": "trx Lorient_KMA",
|
"src-tp-id": "trx Lorient_KMA",
|
||||||
"dst-tp-id": "trx Vannes_KBE",
|
"dst-tp-id": "trx Vannes_KBE",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
"trx_mode": null,
|
"trx_mode": null,
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -22,15 +22,12 @@
|
|||||||
"output-power": 0.0012589254117941673,
|
"output-power": 0.0012589254117941673,
|
||||||
"path_bandwidth": 100000000000.0
|
"path_bandwidth": 100000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "1",
|
"request-id": "1",
|
||||||
"source": "Brest_KLA",
|
"source": "trx Brest_KLA",
|
||||||
"destination": "Vannes_KBE",
|
"destination": "trx Vannes_KBE",
|
||||||
"src-tp-id": "trx Brest_KLA",
|
"src-tp-id": "trx Brest_KLA",
|
||||||
"dst-tp-id": "trx Vannes_KBE",
|
"dst-tp-id": "trx Vannes_KBE",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -40,8 +37,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -50,66 +47,42 @@
|
|||||||
"path_bandwidth": 200000000000.0
|
"path_bandwidth": 200000000000.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
"explicit-route-objects": {
|
||||||
"explicit-route-include-objects": [
|
"route-object-include-exclude": [
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 0,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Brest_KLA",
|
"node-id": "roadm Brest_KLA",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 1,
|
"index": 1,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Lannion_CAS",
|
"node-id": "roadm Lannion_CAS",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 2,
|
"index": 2,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Lorient_KMA",
|
"node-id": "roadm Lorient_KMA",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 3,
|
"index": 3,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Vannes_KBE",
|
"node-id": "roadm Vannes_KBE",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -117,8 +90,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "3",
|
"request-id": "3",
|
||||||
"source": "Lannion_CAS",
|
"source": "trx Lannion_CAS",
|
||||||
"destination": "Rennes_STA",
|
"destination": "trx Rennes_STA",
|
||||||
"src-tp-id": "trx Lannion_CAS",
|
"src-tp-id": "trx Lannion_CAS",
|
||||||
"dst-tp-id": "trx Rennes_STA",
|
"dst-tp-id": "trx Rennes_STA",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -128,8 +101,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -137,15 +110,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": 60000000000.0
|
"path_bandwidth": 60000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "4",
|
"request-id": "4",
|
||||||
"source": "Rennes_STA",
|
"source": "trx Rennes_STA",
|
||||||
"destination": "Lannion_CAS",
|
"destination": "trx Lannion_CAS",
|
||||||
"src-tp-id": "trx Rennes_STA",
|
"src-tp-id": "trx Rennes_STA",
|
||||||
"dst-tp-id": "trx Lannion_CAS",
|
"dst-tp-id": "trx Lannion_CAS",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -155,8 +125,8 @@
|
|||||||
"trx_mode": null,
|
"trx_mode": null,
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 75000000000.0,
|
"spacing": 75000000000.0,
|
||||||
@@ -164,15 +134,12 @@
|
|||||||
"output-power": 0.0019952623149688794,
|
"output-power": 0.0019952623149688794,
|
||||||
"path_bandwidth": 150000000000.0
|
"path_bandwidth": 150000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "5",
|
"request-id": "5",
|
||||||
"source": "Rennes_STA",
|
"source": "trx Rennes_STA",
|
||||||
"destination": "Lannion_CAS",
|
"destination": "trx Lannion_CAS",
|
||||||
"src-tp-id": "trx Rennes_STA",
|
"src-tp-id": "trx Rennes_STA",
|
||||||
"dst-tp-id": "trx Lannion_CAS",
|
"dst-tp-id": "trx Lannion_CAS",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -182,8 +149,8 @@
|
|||||||
"trx_mode": "mode 2",
|
"trx_mode": "mode 2",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 75000000000.0,
|
"spacing": 75000000000.0,
|
||||||
@@ -191,15 +158,12 @@
|
|||||||
"output-power": 0.0019952623149688794,
|
"output-power": 0.0019952623149688794,
|
||||||
"path_bandwidth": 20000000000.0
|
"path_bandwidth": 20000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "6",
|
"request-id": "6",
|
||||||
"source": "Lannion_CAS",
|
"source": "trx Lannion_CAS",
|
||||||
"destination": "Lorient_KMA",
|
"destination": "trx Lorient_KMA",
|
||||||
"src-tp-id": "trx Lannion_CAS",
|
"src-tp-id": "trx Lannion_CAS",
|
||||||
"dst-tp-id": "trx Lorient_KMA",
|
"dst-tp-id": "trx Lorient_KMA",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -209,8 +173,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -218,15 +182,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "7",
|
"request-id": "7",
|
||||||
"source": "Lannion_CAS",
|
"source": "trx Lannion_CAS",
|
||||||
"destination": "Lorient_KMA",
|
"destination": "trx Lorient_KMA",
|
||||||
"src-tp-id": "trx Lannion_CAS",
|
"src-tp-id": "trx Lannion_CAS",
|
||||||
"dst-tp-id": "trx Lorient_KMA",
|
"dst-tp-id": "trx Lorient_KMA",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -236,8 +197,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -245,15 +206,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 400000000000.0
|
"path_bandwidth": 400000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "7b",
|
"request-id": "7b",
|
||||||
"source": "Lannion_CAS",
|
"source": "trx Lannion_CAS",
|
||||||
"destination": "Lorient_KMA",
|
"destination": "trx Lorient_KMA",
|
||||||
"src-tp-id": "trx Lannion_CAS",
|
"src-tp-id": "trx Lannion_CAS",
|
||||||
"dst-tp-id": "trx Lorient_KMA",
|
"dst-tp-id": "trx Lorient_KMA",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -263,8 +221,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 75000000000.0,
|
"spacing": 75000000000.0,
|
||||||
@@ -272,9 +230,6 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 400000000000.0
|
"path_bandwidth": 400000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -282,9 +237,8 @@
|
|||||||
{
|
{
|
||||||
"synchronization-id": "3",
|
"synchronization-id": "3",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "false",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"3",
|
"3",
|
||||||
"1"
|
"1"
|
||||||
@@ -294,9 +248,8 @@
|
|||||||
{
|
{
|
||||||
"synchronization-id": "4",
|
"synchronization-id": "4",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "false",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"4",
|
"4",
|
||||||
"5"
|
"5"
|
||||||
|
|||||||
@@ -55,16 +55,18 @@ def requests_from_json(json_data,equipment):
|
|||||||
# init all params from request
|
# init all params from request
|
||||||
params = {}
|
params = {}
|
||||||
params['request_id'] = req['request-id']
|
params['request_id'] = req['request-id']
|
||||||
params['source'] = req['src-tp-id']
|
params['source'] = req['source']
|
||||||
params['destination'] = req['dst-tp-id']
|
params['destination'] = req['destination']
|
||||||
params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type']
|
params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type']
|
||||||
params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode']
|
params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode']
|
||||||
params['format'] = params['trx_mode']
|
params['format'] = params['trx_mode']
|
||||||
nd_list = req['optimizations']['explicit-route-include-objects']
|
|
||||||
params['nodes_list'] = [n['unnumbered-hop']['node-id'] for n in nd_list]
|
|
||||||
params['loose_list'] = [n['unnumbered-hop']['hop-type'] for n in nd_list]
|
|
||||||
params['spacing'] = req['path-constraints']['te-bandwidth']['spacing']
|
params['spacing'] = req['path-constraints']['te-bandwidth']['spacing']
|
||||||
|
try :
|
||||||
|
nd_list = req['explicit-route-objects']['route-object-include-exclude']
|
||||||
|
except KeyError:
|
||||||
|
nd_list = []
|
||||||
|
params['nodes_list'] = [n['num-unnum-hop']['node-id'] for n in nd_list]
|
||||||
|
params['loose_list'] = [n['num-unnum-hop']['hop-type'] for n in nd_list]
|
||||||
# recover trx physical param (baudrate, ...) from type and mode
|
# recover trx physical param (baudrate, ...) from type and mode
|
||||||
# in trx_mode_params optical power is read from equipment['SI']['default'] and
|
# in trx_mode_params optical power is read from equipment['SI']['default'] and
|
||||||
# nb_channel is computed based on min max frequency and spacing
|
# nb_channel is computed based on min max frequency and spacing
|
||||||
@@ -73,20 +75,24 @@ def requests_from_json(json_data,equipment):
|
|||||||
# print(trx_params['min_spacing'])
|
# print(trx_params['min_spacing'])
|
||||||
# optical power might be set differently in the request. if it is indicated then the
|
# optical power might be set differently in the request. if it is indicated then the
|
||||||
# params['power'] is updated
|
# params['power'] is updated
|
||||||
|
try:
|
||||||
if req['path-constraints']['te-bandwidth']['output-power']:
|
if req['path-constraints']['te-bandwidth']['output-power']:
|
||||||
params['power'] = req['path-constraints']['te-bandwidth']['output-power']
|
params['power'] = req['path-constraints']['te-bandwidth']['output-power']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
# same process for nb-channel
|
# same process for nb-channel
|
||||||
f_min = params['f_min']
|
f_min = params['f_min']
|
||||||
f_max_from_si = params['f_max']
|
f_max_from_si = params['f_max']
|
||||||
if req['path-constraints']['te-bandwidth']['max-nb-of-channel'] is not None :
|
try:
|
||||||
|
if req['path-constraints']['te-bandwidth']['max-nb-of-channel'] is not None:
|
||||||
nch = req['path-constraints']['te-bandwidth']['max-nb-of-channel']
|
nch = req['path-constraints']['te-bandwidth']['max-nb-of-channel']
|
||||||
params['nb_channel'] = nch
|
params['nb_channel'] = nch
|
||||||
spacing = params['spacing']
|
spacing = params['spacing']
|
||||||
params['f_max'] = f_min + nch*spacing
|
params['f_max'] = f_min + nch*spacing
|
||||||
else :
|
else :
|
||||||
params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing'])
|
params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing'])
|
||||||
|
except KeyError:
|
||||||
|
params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing'])
|
||||||
consistency_check(params, f_max_from_si)
|
consistency_check(params, f_max_from_si)
|
||||||
|
|
||||||
try :
|
try :
|
||||||
@@ -122,15 +128,20 @@ def consistency_check(params, f_max_from_si):
|
|||||||
|
|
||||||
def disjunctions_from_json(json_data):
|
def disjunctions_from_json(json_data):
|
||||||
disjunctions_list = []
|
disjunctions_list = []
|
||||||
|
try:
|
||||||
|
temp_test = json_data['synchronization']
|
||||||
|
except KeyError:
|
||||||
|
temp_test = []
|
||||||
|
if temp_test:
|
||||||
for snc in json_data['synchronization']:
|
for snc in json_data['synchronization']:
|
||||||
params = {}
|
params = {}
|
||||||
params['disjunction_id'] = snc['synchronization-id']
|
params['disjunction_id'] = snc['synchronization-id']
|
||||||
params['relaxable'] = snc['svec']['relaxable']
|
params['relaxable'] = snc['svec']['relaxable']
|
||||||
params['link_diverse'] = snc['svec']['link-diverse']
|
params['link_diverse'] = 'link' in snc['svec']['disjointness']
|
||||||
params['node_diverse'] = snc['svec']['node-diverse']
|
params['node_diverse'] = 'node' in snc['svec']['disjointness']
|
||||||
params['disjunctions_req'] = snc['svec']['request-id-number']
|
params['disjunctions_req'] = snc['svec']['request-id-number']
|
||||||
disjunctions_list.append(Disjunction(**params))
|
disjunctions_list.append(Disjunction(**params))
|
||||||
|
|
||||||
return disjunctions_list
|
return disjunctions_list
|
||||||
|
|
||||||
|
|
||||||
@@ -205,7 +216,7 @@ def correct_route_list(network, pathreqlist):
|
|||||||
# prepares the format of route list of nodes to be consistant
|
# prepares the format of route list of nodes to be consistant
|
||||||
# remove wrong names, remove endpoints
|
# remove wrong names, remove endpoints
|
||||||
# also correct source and destination
|
# also correct source and destination
|
||||||
anytype = [n.uid for n in network.nodes() if not isinstance(n, Transceiver) and not isinstance(n, Fiber)]
|
anytype = [n.uid for n in network.nodes()]
|
||||||
# TODO there is a problem of identification of fibers in case of parallel fibers bitween two adjacent roadms
|
# TODO there is a problem of identification of fibers in case of parallel fibers bitween two adjacent roadms
|
||||||
# so fiber constraint is not supported
|
# so fiber constraint is not supported
|
||||||
transponders = [n.uid for n in network.nodes() if isinstance(n, Transceiver)]
|
transponders = [n.uid for n in network.nodes() if isinstance(n, Transceiver)]
|
||||||
@@ -214,9 +225,11 @@ def correct_route_list(network, pathreqlist):
|
|||||||
# replace possibly wrong name with a formated roadm name
|
# replace possibly wrong name with a formated roadm name
|
||||||
# print(n_id)
|
# print(n_id)
|
||||||
if n_id not in anytype :
|
if n_id not in anytype :
|
||||||
|
# find nodes name that include constraint among all possible names except
|
||||||
|
# transponders (not yet supported as constraints).
|
||||||
nodes_suggestion = [uid for uid in anytype \
|
nodes_suggestion = [uid for uid in anytype \
|
||||||
if n_id.lower() in uid.lower()]
|
if n_id.lower() in uid.lower() and uid not in transponders]
|
||||||
if pathreq.loose_list[i] == 'loose':
|
if pathreq.loose_list[i] == 'LOOSE':
|
||||||
if len(nodes_suggestion)>0 :
|
if len(nodes_suggestion)>0 :
|
||||||
new_n = nodes_suggestion[0]
|
new_n = nodes_suggestion[0]
|
||||||
print(f'invalid route node specified:\
|
print(f'invalid route node specified:\
|
||||||
@@ -257,7 +270,7 @@ def correct_disjn(disjn):
|
|||||||
|
|
||||||
def path_result_json(pathresult):
|
def path_result_json(pathresult):
|
||||||
data = {
|
data = {
|
||||||
'path': [n.json for n in pathresult]
|
'response': [n.json for n in pathresult]
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,9 @@ def main(network, equipment, source, destination, sim_params, req=None):
|
|||||||
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f} dBm:')
|
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f} dBm:')
|
||||||
else:
|
else:
|
||||||
print(f'\nTransmission results:')
|
print(f'\nTransmission results:')
|
||||||
print(f' Final SNR total (signal bw): {ansi_escapes.cyan}{mean(destination.snr):.02f} dB{ansi_escapes.reset}')
|
print(f' Final SNR total (0.1 nm): {ansi_escapes.cyan}{mean(destination.snr_01nm):.02f} dB{ansi_escapes.reset}')
|
||||||
|
else:
|
||||||
|
print(path[-1])
|
||||||
|
|
||||||
#print(f'\n !!!!!!!!!!!!!!!!! TEST POINT !!!!!!!!!!!!!!!!!!!!!')
|
#print(f'\n !!!!!!!!!!!!!!!!! TEST POINT !!!!!!!!!!!!!!!!!!!!!')
|
||||||
#print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}')
|
#print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}')
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from collections import namedtuple
|
|||||||
|
|
||||||
from gnpy.core.node import Node
|
from gnpy.core.node import Node
|
||||||
from gnpy.core.units import UNITS
|
from gnpy.core.units import UNITS
|
||||||
from gnpy.core.utils import lin2db, db2lin, itufs, itufl, snr_sum
|
from gnpy.core.utils import lin2db, db2lin, arrange_frequencies, snr_sum
|
||||||
from gnpy.core.science_utils import propagate_raman_fiber, _psi
|
from gnpy.core.science_utils import propagate_raman_fiber, _psi
|
||||||
|
|
||||||
class Transceiver(Node):
|
class Transceiver(Node):
|
||||||
@@ -615,7 +615,7 @@ class Edfa(Node):
|
|||||||
self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple
|
self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple
|
||||||
"""
|
"""
|
||||||
# TODO|jla: read amplifier actual frequencies from additional params in json
|
# TODO|jla: read amplifier actual frequencies from additional params in json
|
||||||
amplifier_freq = itufl(len(self.params.dgt), self.params.f_min, self.params.f_max) # Hz
|
amplifier_freq = arrange_frequencies(len(self.params.dgt), self.params.f_min, self.params.f_max) # Hz
|
||||||
self.channel_freq = frequencies
|
self.channel_freq = frequencies
|
||||||
self.interpol_dgt = interp(self.channel_freq, amplifier_freq, self.params.dgt)
|
self.interpol_dgt = interp(self.channel_freq, amplifier_freq, self.params.dgt)
|
||||||
|
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ class Path_request:
|
|||||||
f'baud_rate:\t{temp} Gbaud',
|
f'baud_rate:\t{temp} Gbaud',
|
||||||
f'bit_rate:\t{temp2} Gb/s',
|
f'bit_rate:\t{temp2} Gb/s',
|
||||||
f'spacing:\t{self.spacing * 1e-9} GHz',
|
f'spacing:\t{self.spacing * 1e-9} GHz',
|
||||||
f'power: \t{round(lin2db(self.power)+30,2)} dBm',
|
f'power: \t{round(lin2db(self.power)+30, 2)} dBm',
|
||||||
f'nb channels: \t{self.nb_channel}',
|
f'nb channels: \t{self.nb_channel}',
|
||||||
f'path_bandwidth: \t{round(self.path_bandwidth * 1e-9,2)} Gbit/s',
|
f'path_bandwidth: \t{round(self.path_bandwidth * 1e-9, 2)} Gbit/s',
|
||||||
f'nodes-list:\t{self.nodes_list}',
|
f'nodes-list:\t{self.nodes_list}',
|
||||||
f'loose-list:\t{self.loose_list}'
|
f'loose-list:\t{self.loose_list}'
|
||||||
'\n'])
|
'\n'])
|
||||||
@@ -115,114 +115,63 @@ class Result_element(Element):
|
|||||||
self.path_id = path_request.request_id
|
self.path_id = path_request.request_id
|
||||||
self.path_request = path_request
|
self.path_request = path_request
|
||||||
self.computed_path = computed_path
|
self.computed_path = computed_path
|
||||||
hop_type = []
|
|
||||||
if len(computed_path)>0 :
|
|
||||||
for e in computed_path :
|
|
||||||
if isinstance(e, Transceiver) :
|
|
||||||
hop_type.append(' - '.join([path_request.tsp,path_request.tsp_mode]))
|
|
||||||
else:
|
|
||||||
hop_type.append('not recorded')
|
|
||||||
else:
|
|
||||||
# TODO differentiate empty path in case not feasible because of tsp or not feasible because
|
|
||||||
# ther is no path connecting the nodes (whatever the tsp)
|
|
||||||
mode = 'not feasible with this transponder'
|
|
||||||
hop_type = ' - '.join([path_request.tsp,mode])
|
|
||||||
self.hop_type = hop_type
|
|
||||||
uid = property(lambda self: repr(self))
|
uid = property(lambda self: repr(self))
|
||||||
@property
|
@property
|
||||||
def pathresult(self):
|
def pathresult(self):
|
||||||
if not self.computed_path:
|
if not self.computed_path:
|
||||||
return {
|
return {
|
||||||
'path-id': self.path_id,
|
'response-id': self.path_id,
|
||||||
'path-properties':{
|
'no-path': "Response without path information, due to failure performing the path computation"
|
||||||
'path-metric': [
|
|
||||||
{
|
|
||||||
'metric-type': 'SNR@bandwidth',
|
|
||||||
'accumulative-value': 'None'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'metric-type': 'SNR@0.1nm',
|
|
||||||
'accumulative-value': 'None'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'metric-type': 'OSNR@bandwidth',
|
|
||||||
'accumulative-value': 'None'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'metric-type': 'OSNR@0.1nm',
|
|
||||||
'accumulative-value': 'None'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'metric-type': 'reference_power',
|
|
||||||
'accumulative-value': self.path_request.power
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'metric-type': 'path_bandwidth',
|
|
||||||
'accumulative-value': self.path_request.path_bandwidth
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'path-srlgs': {
|
|
||||||
'usage': 'not used yet',
|
|
||||||
'values': 'not used yet'
|
|
||||||
},
|
|
||||||
'path-route-objects': [
|
|
||||||
{
|
|
||||||
'path-route-object': {
|
|
||||||
'index': 0,
|
|
||||||
'unnumbered-hop': {
|
|
||||||
'node-id': self.path_request.source,
|
|
||||||
'link-tp-id': self.path_request.source,
|
|
||||||
'hop-type': self.hop_type,
|
|
||||||
'direction': 'not used'
|
|
||||||
},
|
|
||||||
'label-hop': {
|
|
||||||
'te-label': {
|
|
||||||
'generic': 'not used yet',
|
|
||||||
'direction': 'not used yet'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'path-route-object': {
|
|
||||||
'index': 1,
|
|
||||||
'unnumbered-hop': {
|
|
||||||
'node-id': self.path_request.destination,
|
|
||||||
'link-tp-id': self.path_request.destination,
|
|
||||||
'hop-type': self.hop_type,
|
|
||||||
'direction': 'not used'
|
|
||||||
},
|
|
||||||
'label-hop': {
|
|
||||||
'te-label': {
|
|
||||||
'generic': 'not used yet',
|
|
||||||
'direction': 'not used yet'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return {
|
index = 0
|
||||||
'path-id': self.path_id,
|
pro_list = []
|
||||||
|
for element in self.computed_path:
|
||||||
|
temp = {
|
||||||
|
'path-route-object': {
|
||||||
|
'index': index,
|
||||||
|
'num-unnum-hop': {
|
||||||
|
'node-id': element.uid,
|
||||||
|
'link-tp-id': element.uid,
|
||||||
|
# TODO change index in order to insert transponder attribute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pro_list.append(temp)
|
||||||
|
index += 1
|
||||||
|
if isinstance(element, Transceiver):
|
||||||
|
temp = {
|
||||||
|
'path-route-object': {
|
||||||
|
'index': index,
|
||||||
|
'transponder' : {
|
||||||
|
'transponder-type' : self.path_request.tsp,
|
||||||
|
'transponder-mode' : self.path_request.tsp_mode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pro_list.append(temp)
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
response = {
|
||||||
|
'response-id': self.path_id,
|
||||||
'path-properties':{
|
'path-properties':{
|
||||||
'path-metric': [
|
'path-metric': [
|
||||||
{
|
{
|
||||||
'metric-type': 'SNR@bandwidth',
|
'metric-type': 'SNR-bandwidth',
|
||||||
'accumulative-value': round(mean(self.computed_path[-1].snr),2)
|
'accumulative-value': round(mean(self.computed_path[-1].snr), 2)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'metric-type': 'SNR@0.1nm',
|
'metric-type': 'SNR-0.1nm',
|
||||||
'accumulative-value': round(mean(self.computed_path[-1].snr+lin2db(self.path_request.baud_rate/12.5e9)),2)
|
'accumulative-value': round(mean(self.computed_path[-1]. snr + \
|
||||||
|
lin2db(self.path_request.baud_rate/12.5e9)), 2)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'metric-type': 'OSNR@bandwidth',
|
'metric-type': 'OSNR-bandwidth',
|
||||||
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase),2)
|
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase), 2)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'metric-type': 'OSNR@0.1nm',
|
'metric-type': 'OSNR-0.1nm',
|
||||||
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm),2)
|
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm), 2)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'metric-type': 'reference_power',
|
'metric-type': 'reference_power',
|
||||||
@@ -233,31 +182,10 @@ class Result_element(Element):
|
|||||||
'accumulative-value': self.path_request.path_bandwidth
|
'accumulative-value': self.path_request.path_bandwidth
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'path-srlgs': {
|
'path-route-objects': pro_list
|
||||||
'usage': 'not used yet',
|
|
||||||
'values': 'not used yet'
|
|
||||||
},
|
|
||||||
'path-route-objects': [
|
|
||||||
{
|
|
||||||
'path-route-object': {
|
|
||||||
'index': self.computed_path.index(n),
|
|
||||||
'unnumbered-hop': {
|
|
||||||
'node-id': n.uid,
|
|
||||||
'link-tp-id': n.uid,
|
|
||||||
'hop-type': self.hop_type[self.computed_path.index(n)],
|
|
||||||
'direction': 'not used'
|
|
||||||
},
|
|
||||||
'label-hop': {
|
|
||||||
'te-label': {
|
|
||||||
'generic': 'not used yet',
|
|
||||||
'direction': 'not used yet'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} for n in self.computed_path
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return response
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
@@ -319,12 +247,26 @@ def compute_constrained_path(network, req):
|
|||||||
candidate.sort(key=lambda x: sum(network.get_edge_data(x[i],x[i+1])['weight'] for i in range(len(x)-2)))
|
candidate.sort(key=lambda x: sum(network.get_edge_data(x[i],x[i+1])['weight'] for i in range(len(x)-2)))
|
||||||
total_path = candidate[0]
|
total_path = candidate[0]
|
||||||
else:
|
else:
|
||||||
if req.loose_list[req.nodes_list.index(n)] == 'loose':
|
# TODO: better account for individual loose and strict node
|
||||||
print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list} in network topology'+ '\x1b[0m')
|
# to ease: suppose that one strict makes the whole liste strict (except for the
|
||||||
|
# last node which is the transceiver)
|
||||||
|
# if all nodes i n node_list are LOOSE constraint, skip the constraints and find
|
||||||
|
# a path w/o constraints, else there is no possible path
|
||||||
|
if nodes_list[:-len("STRICT")]:
|
||||||
|
print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing ' +\
|
||||||
|
f'{[el.uid for el in nodes_list[:-len("STRICT")]]} in network topology'+ '\x1b[0m')
|
||||||
|
else:
|
||||||
|
print(f'\x1b[1;33;40m'+f'User include_node constraints could not be applied ' +\
|
||||||
|
f'(invalid names specified)'+ '\x1b[0m')
|
||||||
|
if 'STRICT' not in req.loose_list[:-len('STRICT')]:
|
||||||
|
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path with user_' +\
|
||||||
|
f'include node constraints' + '\x1b[0m'
|
||||||
|
logger.info(msg)
|
||||||
print(f'constraint ignored')
|
print(f'constraint ignored')
|
||||||
total_path = dijkstra_path(network, source, destination, weight = 'weight')
|
total_path = dijkstra_path(network, source, destination, weight = 'weight')
|
||||||
else:
|
else:
|
||||||
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list}.\nNo path computed'+ '\x1b[0m'
|
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path with user ' +\
|
||||||
|
f'include node constraints.\nNo path computed'+ '\x1b[0m'
|
||||||
logger.critical(msg)
|
logger.critical(msg)
|
||||||
print(msg)
|
print(msg)
|
||||||
total_path = []
|
total_path = []
|
||||||
@@ -468,25 +410,50 @@ def jsontocsv(json_data,equipment,fileout):
|
|||||||
# and write results in an CSV file
|
# and write results in an CSV file
|
||||||
|
|
||||||
mywriter = writer(fileout)
|
mywriter = writer(fileout)
|
||||||
mywriter.writerow(('path-id','source','destination','path_bandwidth','Pass?',\
|
mywriter.writerow(('response-id','source','destination','path_bandwidth','Pass?',\
|
||||||
'nb of tsp pairs','total cost','transponder-type','transponder-mode',\
|
'nb of tsp pairs','total cost','transponder-type','transponder-mode',\
|
||||||
'OSNR@0.1nm','SNR@0.1nm','SNR@bandwidth','baud rate (Gbaud)',\
|
'OSNR-0.1nm','SNR-0.1nm','SNR-bandwidth','baud rate (Gbaud)',\
|
||||||
'input power (dBm)','path'))
|
'input power (dBm)','path'))
|
||||||
tspjsondata = equipment['Transceiver']
|
tspjsondata = equipment['Transceiver']
|
||||||
#print(tspjsondata)
|
#print(tspjsondata)
|
||||||
for p in json_data['path']:
|
|
||||||
path_id = p['path-id']
|
|
||||||
source = p['path-properties']['path-route-objects'][0]\
|
|
||||||
['path-route-object']['unnumbered-hop']['node-id']
|
|
||||||
destination = p['path-properties']['path-route-objects'][-1]\
|
|
||||||
['path-route-object']['unnumbered-hop']['node-id']
|
|
||||||
# selects only roadm nodes
|
|
||||||
pth = ' | '.join([ e['path-route-object']['unnumbered-hop']['node-id']
|
|
||||||
for e in p['path-properties']['path-route-objects']
|
|
||||||
if e['path-route-object']['unnumbered-hop']['node-id'].startswith('roadm') or e['path-route-object']['unnumbered-hop']['node-id'].startswith('Edfa')])
|
|
||||||
|
|
||||||
[tsp,mode] = p['path-properties']['path-route-objects'][0]\
|
for pth_el in json_data['response']:
|
||||||
['path-route-object']['unnumbered-hop']['hop-type'].split(' - ')
|
path_id = pth_el['response-id']
|
||||||
|
try:
|
||||||
|
if pth_el['no-path'] :
|
||||||
|
source = ''
|
||||||
|
destination = ''
|
||||||
|
tsp = ''
|
||||||
|
mode = ''
|
||||||
|
isok = False
|
||||||
|
nb_tsp = 0
|
||||||
|
pthbdbw = ''
|
||||||
|
rosnr = ''
|
||||||
|
rsnr = ''
|
||||||
|
rsnrb = ''
|
||||||
|
br = ''
|
||||||
|
pw = ''
|
||||||
|
total_cost = ''
|
||||||
|
pth = ''
|
||||||
|
except KeyError:
|
||||||
|
|
||||||
|
source = pth_el['path-properties']['path-route-objects'][0]\
|
||||||
|
['path-route-object']['num-unnum-hop']['node-id']
|
||||||
|
destination = pth_el['path-properties']['path-route-objects'][-2]\
|
||||||
|
['path-route-object']['num-unnum-hop']['node-id']
|
||||||
|
# selects only roadm nodes
|
||||||
|
temp = []
|
||||||
|
for e in pth_el['path-properties']['path-route-objects']:
|
||||||
|
try :
|
||||||
|
temp.append(e['path-route-object']['num-unnum-hop']['node-id'])
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
pth = ' | '.join(temp)
|
||||||
|
|
||||||
|
temp_tsp = pth_el['path-properties']['path-route-objects'][1]\
|
||||||
|
['path-route-object']['transponder']
|
||||||
|
tsp = temp_tsp['transponder-type']
|
||||||
|
mode = temp_tsp['transponder-mode']
|
||||||
|
|
||||||
# find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format)
|
# find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format)
|
||||||
# loading equipment already tests the existence of tsp type and mode:
|
# loading equipment already tests the existence of tsp type and mode:
|
||||||
@@ -496,17 +463,17 @@ def jsontocsv(json_data,equipment,fileout):
|
|||||||
# else:
|
# else:
|
||||||
# [minosnr, baud_rate, bit_rate] = ['','','','']
|
# [minosnr, baud_rate, bit_rate] = ['','','','']
|
||||||
output_snr = next(e['accumulative-value']
|
output_snr = next(e['accumulative-value']
|
||||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@0.1nm')
|
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'SNR-0.1nm')
|
||||||
output_snrbandwidth = next(e['accumulative-value']
|
output_snrbandwidth = next(e['accumulative-value']
|
||||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@bandwidth')
|
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'SNR-bandwidth')
|
||||||
output_osnr = next(e['accumulative-value']
|
output_osnr = next(e['accumulative-value']
|
||||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@0.1nm')
|
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'OSNR-0.1nm')
|
||||||
output_osnrbandwidth = next(e['accumulative-value']
|
output_osnrbandwidth = next(e['accumulative-value']
|
||||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@bandwidth')
|
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'OSNR-bandwidth')
|
||||||
power = next(e['accumulative-value']
|
power = next(e['accumulative-value']
|
||||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'reference_power')
|
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'reference_power')
|
||||||
path_bandwidth = next(e['accumulative-value']
|
path_bandwidth = next(e['accumulative-value']
|
||||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'path_bandwidth')
|
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'path_bandwidth')
|
||||||
if isinstance(output_snr, str):
|
if isinstance(output_snr, str):
|
||||||
isok = False
|
isok = False
|
||||||
nb_tsp = 0
|
nb_tsp = 0
|
||||||
@@ -527,6 +494,7 @@ def jsontocsv(json_data,equipment,fileout):
|
|||||||
br = round(baud_rate*1e-9,2)
|
br = round(baud_rate*1e-9,2)
|
||||||
pw = round(lin2db(power)+30,2)
|
pw = round(lin2db(power)+30,2)
|
||||||
total_cost = nb_tsp * cost
|
total_cost = nb_tsp * cost
|
||||||
|
|
||||||
mywriter.writerow((path_id,
|
mywriter.writerow((path_id,
|
||||||
source,
|
source,
|
||||||
destination,
|
destination,
|
||||||
@@ -759,9 +727,10 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
|||||||
testispartok = False
|
testispartok = False
|
||||||
#break
|
#break
|
||||||
else:
|
else:
|
||||||
if 'loose' in allpaths[id(p)].req.loose_list:
|
if 'LOOSE' in allpaths[id(p)].req.loose_list:
|
||||||
logger.info(f'Could not apply route constraint'+
|
logger.info(f'Could not apply route constraint'+
|
||||||
f'{allpaths[id(p)].req.nodes_list} on request {allpaths[id(p)].req.request_id}')
|
f'{allpaths[id(p)].req.nodes_list} on request' +\
|
||||||
|
f' {allpaths[id(p)].req.request_id}')
|
||||||
else :
|
else :
|
||||||
logger.info(f'removing last solution from candidate paths\n{sol}')
|
logger.info(f'removing last solution from candidate paths\n{sol}')
|
||||||
testispartok = False
|
testispartok = False
|
||||||
@@ -798,7 +767,7 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
|
|||||||
for req in pathreqlist :
|
for req in pathreqlist :
|
||||||
req.nodes_list.append(req.destination)
|
req.nodes_list.append(req.destination)
|
||||||
# we assume that the destination is a strict constraint
|
# we assume that the destination is a strict constraint
|
||||||
req.loose_list.append('strict')
|
req.loose_list.append('STRICT')
|
||||||
if req in pathreqlist_simple:
|
if req in pathreqlist_simple:
|
||||||
path_res_list.append(compute_constrained_path(network, req))
|
path_res_list.append(compute_constrained_path(network, req))
|
||||||
else:
|
else:
|
||||||
@@ -890,19 +859,19 @@ def compare_reqs(req1,req2,disjlist) :
|
|||||||
req1.format == req2.format and \
|
req1.format == req2.format and \
|
||||||
req1.OSNR == req2.OSNR and \
|
req1.OSNR == req2.OSNR and \
|
||||||
req1.roll_off == req2.roll_off and \
|
req1.roll_off == req2.roll_off and \
|
||||||
same_disj :
|
same_disj:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def requests_aggregation(pathreqlist,disjlist) :
|
def requests_aggregation(pathreqlist,disjlist):
|
||||||
# this function aggregates requests so that if several requests
|
# this function aggregates requests so that if several requests
|
||||||
# exist between same source and destination and with same transponder type
|
# exist between same source and destination and with same transponder type
|
||||||
# todo maybe add conditions on mode ??, spacing ...
|
# todo maybe add conditions on mode ??, spacing ...
|
||||||
# currently if undefined takes the default values
|
# currently if undefined takes the default values
|
||||||
local_list = pathreqlist.copy()
|
local_list = pathreqlist.copy()
|
||||||
for req in pathreqlist:
|
for req in pathreqlist:
|
||||||
for r in local_list :
|
for r in local_list:
|
||||||
if req.request_id != r.request_id and compare_reqs(req, r, disjlist):
|
if req.request_id != r.request_id and compare_reqs(req, r, disjlist):
|
||||||
# aggregate
|
# aggregate
|
||||||
r.path_bandwidth += req.path_bandwidth
|
r.path_bandwidth += req.path_bandwidth
|
||||||
@@ -912,12 +881,12 @@ def requests_aggregation(pathreqlist,disjlist) :
|
|||||||
local_list.remove(req)
|
local_list.remove(req)
|
||||||
# todo change also disjunction req with new demand
|
# todo change also disjunction req with new demand
|
||||||
|
|
||||||
for d in disjlist :
|
for d in disjlist:
|
||||||
if req.request_id in d.disjunctions_req :
|
if req.request_id in d.disjunctions_req:
|
||||||
d.disjunctions_req.remove(req.request_id)
|
d.disjunctions_req.remove(req.request_id)
|
||||||
d.disjunctions_req.append(r.request_id)
|
d.disjunctions_req.append(r.request_id)
|
||||||
for d in disjlist :
|
for d in disjlist:
|
||||||
if temp_r_id in d.disjunctions_req :
|
if temp_r_id in d.disjunctions_req:
|
||||||
disjlist.remove(d)
|
disjlist.remove(d)
|
||||||
break
|
break
|
||||||
return local_list, disjlist
|
return local_list, disjlist
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ class Request_element(Element):
|
|||||||
# excel has automatic number formatting that adds .0 on integer values
|
# excel has automatic number formatting that adds .0 on integer values
|
||||||
# the next lines recover the pure int value, assuming this .0 is unwanted
|
# the next lines recover the pure int value, assuming this .0 is unwanted
|
||||||
self.request_id = correct_xlrd_int_to_str_reading(Request.request_id)
|
self.request_id = correct_xlrd_int_to_str_reading(Request.request_id)
|
||||||
self.source = Request.source
|
self.source = f'trx {Request.source}'
|
||||||
self.destination = Request.destination
|
self.destination = f'trx {Request.destination}'
|
||||||
# TODO: the automatic naming generated by excel parser requires that source and dest name
|
# TODO: the automatic naming generated by excel parser requires that source and dest name
|
||||||
# be a string starting with 'trx' : this is manually added here.
|
# be a string starting with 'trx' : this is manually added here.
|
||||||
self.srctpid = f'trx {Request.source}'
|
self.srctpid = f'trx {Request.source}'
|
||||||
@@ -120,9 +120,9 @@ class Request_element(Element):
|
|||||||
|
|
||||||
# the excel parser applies the same hop-type to all nodes in the route nodes_list.
|
# the excel parser applies the same hop-type to all nodes in the route nodes_list.
|
||||||
# user can change this per node in the generated json
|
# user can change this per node in the generated json
|
||||||
self.loose = 'loose'
|
self.loose = 'LOOSE'
|
||||||
if Request.is_loose == 'no' :
|
if Request.is_loose == 'no' :
|
||||||
self.loose = 'strict'
|
self.loose = 'STRICT'
|
||||||
self.path_bandwidth = None
|
self.path_bandwidth = None
|
||||||
if Request.path_bandwidth is not None:
|
if Request.path_bandwidth is not None:
|
||||||
self.path_bandwidth = Request.path_bandwidth * 1e9
|
self.path_bandwidth = Request.path_bandwidth * 1e9
|
||||||
@@ -132,6 +132,7 @@ class Request_element(Element):
|
|||||||
uid = property(lambda self: repr(self))
|
uid = property(lambda self: repr(self))
|
||||||
@property
|
@property
|
||||||
def pathrequest(self):
|
def pathrequest(self):
|
||||||
|
|
||||||
req_dictionnary = {
|
req_dictionnary = {
|
||||||
'request-id':self.request_id,
|
'request-id':self.request_id,
|
||||||
'source': self.source,
|
'source': self.source,
|
||||||
@@ -143,35 +144,28 @@ class Request_element(Element):
|
|||||||
'technology': 'flexi-grid',
|
'technology': 'flexi-grid',
|
||||||
'trx_type' : self.trx_type,
|
'trx_type' : self.trx_type,
|
||||||
'trx_mode' : self.mode,
|
'trx_mode' : self.mode,
|
||||||
'effective-freq-slot':[{'n': 'null','m': 'null'}] ,
|
'effective-freq-slot':[{'N': 'null', 'M': 'null'}],
|
||||||
'spacing' : self.spacing,
|
'spacing' : self.spacing,
|
||||||
'max-nb-of-channel' : self.nb_channel,
|
'max-nb-of-channel' : self.nb_channel,
|
||||||
'output-power' : self.power
|
'output-power' : self.power
|
||||||
# 'path_bandwidth' : self.path_bandwidth
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
'optimizations': {
|
}
|
||||||
'explicit-route-include-objects': [
|
|
||||||
{
|
if self.nodes_list:
|
||||||
|
req_dictionnary['explicit-route-objects'] = {}
|
||||||
|
temp = {'route-object-include-exclude' : [
|
||||||
|
{'explicit-route-usage': 'route-include-ero',
|
||||||
'index': self.nodes_list.index(node),
|
'index': self.nodes_list.index(node),
|
||||||
'unnumbered-hop':{
|
'num-unnum-hop': {
|
||||||
'node-id': f'{node}',
|
'node-id': f'{node}',
|
||||||
'link-tp-id': 'link-tp-id is not used',
|
'link-tp-id': 'link-tp-id is not used',
|
||||||
'hop-type': f'{self.loose}',
|
'hop-type': f'{self.loose}',
|
||||||
'direction': 'direction is not used'
|
|
||||||
},
|
|
||||||
'label-hop':{
|
|
||||||
'te-label': {
|
|
||||||
'generic': 'generic is not used',
|
|
||||||
'direction': 'direction is not used'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for node in self.nodes_list]
|
||||||
}
|
}
|
||||||
for node in self.nodes_list
|
req_dictionnary['explicit-route-objects'] = temp
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if self.path_bandwidth is not None:
|
if self.path_bandwidth is not None:
|
||||||
req_dictionnary['path-constraints']['te-bandwidth']['path_bandwidth'] = self.path_bandwidth
|
req_dictionnary['path-constraints']['te-bandwidth']['path_bandwidth'] = self.path_bandwidth
|
||||||
|
|
||||||
@@ -181,12 +175,13 @@ class Request_element(Element):
|
|||||||
if self.disjoint_from :
|
if self.disjoint_from :
|
||||||
return {'synchronization-id':self.request_id,
|
return {'synchronization-id':self.request_id,
|
||||||
'svec': {
|
'svec': {
|
||||||
'relaxable' : 'False',
|
'relaxable' : 'false',
|
||||||
'link-diverse': 'True',
|
'disjointness': 'node link',
|
||||||
'node-diverse': 'True',
|
|
||||||
'request-id-number': [self.request_id]+ [n for n in self.disjoint_from]
|
'request-id-number': [self.request_id]+ [n for n in self.disjoint_from]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
# TO-DO: avoid multiple entries with same synchronisation vectors
|
# TO-DO: avoid multiple entries with same synchronisation vectors
|
||||||
@property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
@@ -201,10 +196,16 @@ def convert_service_sheet(input_filename, eqpt_filename, output_filename='', fil
|
|||||||
output_filename = f'{str(input_filename)[0:len(str(input_filename))-len(str(input_filename.suffixes[0]))]}_services.json'
|
output_filename = f'{str(input_filename)[0:len(str(input_filename))-len(str(input_filename.suffixes[0]))]}_services.json'
|
||||||
# for debug
|
# for debug
|
||||||
# print(json_filename)
|
# print(json_filename)
|
||||||
|
# if there is no sync vector , do not write any synchronization
|
||||||
|
synchro = [n.json[1] for n in req if n.json[1] is not None]
|
||||||
|
if synchro:
|
||||||
data = {
|
data = {
|
||||||
'path-request': [n.json[0] for n in req],
|
'path-request': [n.json[0] for n in req],
|
||||||
'synchronization': [n.json[1] for n in req
|
'synchronization': synchro
|
||||||
if n.json[1] is not None]
|
}
|
||||||
|
else:
|
||||||
|
data = {
|
||||||
|
'path-request': [n.json[0] for n in req]
|
||||||
}
|
}
|
||||||
with open(output_filename, 'w', encoding='utf-8') as f:
|
with open(output_filename, 'w', encoding='utf-8') as f:
|
||||||
f.write(dumps(data, indent=2, ensure_ascii=False))
|
f.write(dumps(data, indent=2, ensure_ascii=False))
|
||||||
|
|||||||
@@ -73,35 +73,19 @@ def c():
|
|||||||
return constants.c
|
return constants.c
|
||||||
|
|
||||||
|
|
||||||
def itufs(spacing, startf=191.35, stopf=196.10):
|
def arrange_frequencies(length, start, stop):
|
||||||
"""Creates an array of frequencies whose default range is
|
"""Create an array of frequencies
|
||||||
191.35-196.10 THz
|
|
||||||
|
|
||||||
:param spacing: Frequency spacing in THz
|
|
||||||
:param starf: Start frequency in THz
|
|
||||||
:param stopf: Stop frequency in THz
|
|
||||||
:type spacing: float
|
|
||||||
:type startf: float
|
|
||||||
:type stopf: float
|
|
||||||
:return an array of frequnecies determined by the spacing parameter
|
|
||||||
:rtype: numpy.ndarray
|
|
||||||
"""
|
|
||||||
return np.arange(startf, stopf + spacing / 2, spacing)
|
|
||||||
|
|
||||||
def itufl(length, startf=191.35, stopf=196.10):
|
|
||||||
"""Creates an array of frequencies whose default range is
|
|
||||||
191.35-196.10 THz
|
|
||||||
|
|
||||||
:param length: number of elements
|
:param length: number of elements
|
||||||
:param starf: Start frequency in THz
|
:param star: Start frequency in THz
|
||||||
:param stopf: Stop frequency in THz
|
:param stop: Stop frequency in THz
|
||||||
:type length: integer
|
:type length: integer
|
||||||
:type startf: float
|
:type start: float
|
||||||
:type stopf: float
|
:type stop: float
|
||||||
:return an array of frequnecies determined by the spacing parameter
|
:return an array of frequencies determined by the spacing parameter
|
||||||
:rtype: numpy.ndarray
|
:rtype: numpy.ndarray
|
||||||
"""
|
"""
|
||||||
return np.linspace(startf, stopf, length)
|
return np.linspace(start, stop, length)
|
||||||
|
|
||||||
def h():
|
def h():
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,40 +1,64 @@
|
|||||||
{
|
{
|
||||||
"paths": [
|
"response": [
|
||||||
{
|
{
|
||||||
"path": {
|
"response-id": null,
|
||||||
"path-id": null,
|
|
||||||
"path-properties": {
|
"path-properties": {
|
||||||
"path-metric": [
|
"path-metric": [
|
||||||
{
|
{
|
||||||
"metric-type": null,
|
"metric-type": "SNR@bandwidth",
|
||||||
|
"accumulative-value": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "SNR@0.1nm",
|
||||||
|
"accumulative-value": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR@bandwidth",
|
||||||
|
"accumulative-value": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR@0.1nm",
|
||||||
|
"accumulative-value": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "reference_power",
|
||||||
|
"accumulative-value": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "path_bandwidth",
|
||||||
"accumulative-value": null
|
"accumulative-value": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"path-srlgs": {
|
|
||||||
"usage": "not used yet",
|
|
||||||
"values": ["not used yet"]
|
|
||||||
},
|
|
||||||
"path-route-objects": [
|
"path-route-objects": [
|
||||||
{
|
{
|
||||||
"path-route-object": {
|
"path-route-object": {
|
||||||
"index": null,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": null,
|
"node-id": null,
|
||||||
"link-tp-id": null,
|
"link-tp-id": null
|
||||||
"hop-type": null,
|
|
||||||
"direction": "not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "not used yet",
|
|
||||||
"direction": "not used yet"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 1,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": null,
|
||||||
|
"transponder-mode": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 2,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": null,
|
||||||
|
"link-tp-id": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ alabaster>=0.7.12,<1
|
|||||||
matplotlib>=3.1.0,<4
|
matplotlib>=3.1.0,<4
|
||||||
networkx>=2.3,<3
|
networkx>=2.3,<3
|
||||||
numpy>=1.16.1,<2
|
numpy>=1.16.1,<2
|
||||||
|
pandas==0.24.2
|
||||||
Pygments>=2.4.2,<3
|
Pygments>=2.4.2,<3
|
||||||
pytest>=4.0.0,<5
|
pytest>=4.0.0,<5
|
||||||
scipy>=1.3.0,<2
|
scipy>=1.3.0,<2
|
||||||
|
|||||||
@@ -6,6 +6,44 @@
|
|||||||
"destination": null,
|
"destination": null,
|
||||||
"src-tp-id": null,
|
"src-tp-id": null,
|
||||||
"dst-tp-id": null,
|
"dst-tp-id": null,
|
||||||
|
"explicit-route-objects": {
|
||||||
|
"route-object-include-exclude": [
|
||||||
|
{
|
||||||
|
"explicit-route-usage": null,
|
||||||
|
"index": null,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": null,
|
||||||
|
"link-tp-id": null,
|
||||||
|
"hop-type": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"explicit-route-usage": null,
|
||||||
|
"index": null,
|
||||||
|
"label-hop": {
|
||||||
|
"N": null,
|
||||||
|
"M": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"explicit-route-usage": null,
|
||||||
|
"index": null,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": null,
|
||||||
|
"transponder-mode": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"explicit-route-usage": null,
|
||||||
|
"index": null,
|
||||||
|
"regenerator": {
|
||||||
|
"regenerator-id": null,
|
||||||
|
"transponder-type": null,
|
||||||
|
"transponder-mode": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
"te-bandwidth": {
|
"te-bandwidth": {
|
||||||
"technology": "flexi-grid",
|
"technology": "flexi-grid",
|
||||||
@@ -22,27 +60,6 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": null
|
"path_bandwidth": null
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": {
|
|
||||||
"route-object-include-object": [
|
|
||||||
{
|
|
||||||
"index": null,
|
|
||||||
"unnumbered-hop": {
|
|
||||||
"node-id": null,
|
|
||||||
"link-tp-id": "link-tp-id is not used",
|
|
||||||
"hop-type": null,
|
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
"synchronization": [
|
"synchronization": [
|
||||||
@@ -50,10 +67,9 @@
|
|||||||
"synchronization-id": null,
|
"synchronization-id": null,
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "True",
|
"relaxable": "True",
|
||||||
"link-diverse": "False",
|
"disjointness": "node link",
|
||||||
"node-diverse": "False",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
null ]
|
null, null ]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Binary file not shown.
866
tests/data/testTopology_response.json
Normal file
866
tests/data/testTopology_response.json
Normal file
@@ -0,0 +1,866 @@
|
|||||||
|
{
|
||||||
|
"response": [
|
||||||
|
{
|
||||||
|
"response-id": "0",
|
||||||
|
"path-properties": {
|
||||||
|
"path-metric": [
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-bandwidth",
|
||||||
|
"accumulative-value": 26.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-0.1nm",
|
||||||
|
"accumulative-value": 30.84
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-bandwidth",
|
||||||
|
"accumulative-value": 26.76
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-0.1nm",
|
||||||
|
"accumulative-value": 30.84
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "reference_power",
|
||||||
|
"accumulative-value": 0.001
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "path_bandwidth",
|
||||||
|
"accumulative-value": 100000000000.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"path-route-objects": [
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 0,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Lorient_KMA",
|
||||||
|
"link-tp-id": "trx Lorient_KMA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 1,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "Voyager",
|
||||||
|
"transponder-mode": "mode 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 2,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Lorient_KMA",
|
||||||
|
"link-tp-id": "roadm Lorient_KMA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 3,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa1_roadm Lorient_KMA",
|
||||||
|
"link-tp-id": "Edfa1_roadm Lorient_KMA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 4,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Lorient_KMA → Vannes_KBE)-F055",
|
||||||
|
"link-tp-id": "fiber (Lorient_KMA → Vannes_KBE)-F055"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 5,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 6,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Vannes_KBE",
|
||||||
|
"link-tp-id": "roadm Vannes_KBE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 7,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Vannes_KBE",
|
||||||
|
"link-tp-id": "trx Vannes_KBE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 8,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "Voyager",
|
||||||
|
"transponder-mode": "mode 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"response-id": "1",
|
||||||
|
"path-properties": {
|
||||||
|
"path-metric": [
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-bandwidth",
|
||||||
|
"accumulative-value": 18.03
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-0.1nm",
|
||||||
|
"accumulative-value": 22.11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-bandwidth",
|
||||||
|
"accumulative-value": 18.57
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-0.1nm",
|
||||||
|
"accumulative-value": 22.65
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "reference_power",
|
||||||
|
"accumulative-value": 0.0012589254117941673
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "path_bandwidth",
|
||||||
|
"accumulative-value": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"path-route-objects": [
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 0,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Brest_KLA",
|
||||||
|
"link-tp-id": "trx Brest_KLA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 1,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "Voyager",
|
||||||
|
"transponder-mode": "mode 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 2,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Brest_KLA",
|
||||||
|
"link-tp-id": "roadm Brest_KLA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 3,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_roadm Brest_KLA",
|
||||||
|
"link-tp-id": "Edfa0_roadm Brest_KLA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 4,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Brest_KLA → Morlaix)-F060",
|
||||||
|
"link-tp-id": "fiber (Brest_KLA → Morlaix)-F060"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 5,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "east fused spans in Morlaix",
|
||||||
|
"link-tp-id": "east fused spans in Morlaix"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 6,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Morlaix → Lannion_CAS)-F059",
|
||||||
|
"link-tp-id": "fiber (Morlaix → Lannion_CAS)-F059"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 7,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "west edfa in Lannion_CAS to Morlaix",
|
||||||
|
"link-tp-id": "west edfa in Lannion_CAS to Morlaix"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 8,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Lannion_CAS",
|
||||||
|
"link-tp-id": "roadm Lannion_CAS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 9,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "east edfa in Lannion_CAS to Corlay",
|
||||||
|
"link-tp-id": "east edfa in Lannion_CAS to Corlay"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 10,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Lannion_CAS → Corlay)-F061",
|
||||||
|
"link-tp-id": "fiber (Lannion_CAS → Corlay)-F061"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 11,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "west fused spans in Corlay",
|
||||||
|
"link-tp-id": "west fused spans in Corlay"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 12,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Corlay → Loudeac)-F010",
|
||||||
|
"link-tp-id": "fiber (Corlay → Loudeac)-F010"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 13,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "west fused spans in Loudeac",
|
||||||
|
"link-tp-id": "west fused spans in Loudeac"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 14,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Loudeac → Lorient_KMA)-F054",
|
||||||
|
"link-tp-id": "fiber (Loudeac → Lorient_KMA)-F054"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 15,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Loudeac → Lorient_KMA)-F054",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Loudeac → Lorient_KMA)-F054"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 16,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Lorient_KMA",
|
||||||
|
"link-tp-id": "roadm Lorient_KMA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 17,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa1_roadm Lorient_KMA",
|
||||||
|
"link-tp-id": "Edfa1_roadm Lorient_KMA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 18,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Lorient_KMA → Vannes_KBE)-F055",
|
||||||
|
"link-tp-id": "fiber (Lorient_KMA → Vannes_KBE)-F055"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 19,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 20,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Vannes_KBE",
|
||||||
|
"link-tp-id": "roadm Vannes_KBE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 21,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Vannes_KBE",
|
||||||
|
"link-tp-id": "trx Vannes_KBE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 22,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "Voyager",
|
||||||
|
"transponder-mode": "mode 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"response-id": "3",
|
||||||
|
"path-properties": {
|
||||||
|
"path-metric": [
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-bandwidth",
|
||||||
|
"accumulative-value": 21.77
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-0.1nm",
|
||||||
|
"accumulative-value": 25.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-bandwidth",
|
||||||
|
"accumulative-value": 24.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-0.1nm",
|
||||||
|
"accumulative-value": 28.29
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "reference_power",
|
||||||
|
"accumulative-value": 0.0012589254117941673
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "path_bandwidth",
|
||||||
|
"accumulative-value": 60000000000.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"path-route-objects": [
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 0,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Lannion_CAS",
|
||||||
|
"link-tp-id": "trx Lannion_CAS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 1,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "vendorA_trx-type1",
|
||||||
|
"transponder-mode": "mode 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 2,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Lannion_CAS",
|
||||||
|
"link-tp-id": "roadm Lannion_CAS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 3,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "east edfa in Lannion_CAS to Stbrieuc",
|
||||||
|
"link-tp-id": "east edfa in Lannion_CAS to Stbrieuc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 4,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Lannion_CAS → Stbrieuc)-F056",
|
||||||
|
"link-tp-id": "fiber (Lannion_CAS → Stbrieuc)-F056"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 5,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "east edfa in Stbrieuc to Rennes_STA",
|
||||||
|
"link-tp-id": "east edfa in Stbrieuc to Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 6,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Stbrieuc → Rennes_STA)-F057",
|
||||||
|
"link-tp-id": "fiber (Stbrieuc → Rennes_STA)-F057"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 7,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Stbrieuc → Rennes_STA)-F057",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Stbrieuc → Rennes_STA)-F057"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 8,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Rennes_STA",
|
||||||
|
"link-tp-id": "roadm Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 9,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Rennes_STA",
|
||||||
|
"link-tp-id": "trx Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 10,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "vendorA_trx-type1",
|
||||||
|
"transponder-mode": "mode 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"response-id": "4",
|
||||||
|
"path-properties": {
|
||||||
|
"path-metric": [
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-bandwidth",
|
||||||
|
"accumulative-value": 15.05
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-0.1nm",
|
||||||
|
"accumulative-value": 22.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-bandwidth",
|
||||||
|
"accumulative-value": 15.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-0.1nm",
|
||||||
|
"accumulative-value": 22.27
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "reference_power",
|
||||||
|
"accumulative-value": 0.001
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "path_bandwidth",
|
||||||
|
"accumulative-value": 150000000000.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"path-route-objects": [
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 0,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Rennes_STA",
|
||||||
|
"link-tp-id": "trx Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 1,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "vendorA_trx-type1",
|
||||||
|
"transponder-mode": "mode 2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 2,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Rennes_STA",
|
||||||
|
"link-tp-id": "roadm Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 3,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa1_roadm Rennes_STA",
|
||||||
|
"link-tp-id": "Edfa1_roadm Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 4,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Rennes_STA → Ploermel)-",
|
||||||
|
"link-tp-id": "fiber (Rennes_STA → Ploermel)-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 5,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "east edfa in Ploermel to Vannes_KBE",
|
||||||
|
"link-tp-id": "east edfa in Ploermel to Vannes_KBE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 6,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Ploermel → Vannes_KBE)-",
|
||||||
|
"link-tp-id": "fiber (Ploermel → Vannes_KBE)-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 7,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Ploermel → Vannes_KBE)-",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Ploermel → Vannes_KBE)-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 8,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Vannes_KBE",
|
||||||
|
"link-tp-id": "roadm Vannes_KBE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 9,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_roadm Vannes_KBE",
|
||||||
|
"link-tp-id": "Edfa0_roadm Vannes_KBE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 10,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Vannes_KBE → Lorient_KMA)-F055",
|
||||||
|
"link-tp-id": "fiber (Vannes_KBE → Lorient_KMA)-F055"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 11,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 12,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Lorient_KMA",
|
||||||
|
"link-tp-id": "roadm Lorient_KMA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 13,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_roadm Lorient_KMA",
|
||||||
|
"link-tp-id": "Edfa0_roadm Lorient_KMA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 14,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Lorient_KMA → Loudeac)-F054",
|
||||||
|
"link-tp-id": "fiber (Lorient_KMA → Loudeac)-F054"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 15,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "east fused spans in Loudeac",
|
||||||
|
"link-tp-id": "east fused spans in Loudeac"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 16,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Loudeac → Corlay)-F010",
|
||||||
|
"link-tp-id": "fiber (Loudeac → Corlay)-F010"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 17,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "east fused spans in Corlay",
|
||||||
|
"link-tp-id": "east fused spans in Corlay"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 18,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Corlay → Lannion_CAS)-F061",
|
||||||
|
"link-tp-id": "fiber (Corlay → Lannion_CAS)-F061"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 19,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "west edfa in Lannion_CAS to Corlay",
|
||||||
|
"link-tp-id": "west edfa in Lannion_CAS to Corlay"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 20,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Lannion_CAS",
|
||||||
|
"link-tp-id": "roadm Lannion_CAS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 21,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Lannion_CAS",
|
||||||
|
"link-tp-id": "trx Lannion_CAS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 22,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "vendorA_trx-type1",
|
||||||
|
"transponder-mode": "mode 2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"response-id": "5",
|
||||||
|
"path-properties": {
|
||||||
|
"path-metric": [
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-bandwidth",
|
||||||
|
"accumulative-value": 21.68
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "SNR-0.1nm",
|
||||||
|
"accumulative-value": 28.77
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-bandwidth",
|
||||||
|
"accumulative-value": 23.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "OSNR-0.1nm",
|
||||||
|
"accumulative-value": 30.79
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "reference_power",
|
||||||
|
"accumulative-value": 0.0019952623149688794
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metric-type": "path_bandwidth",
|
||||||
|
"accumulative-value": 20000000000.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"path-route-objects": [
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 0,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Rennes_STA",
|
||||||
|
"link-tp-id": "trx Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 1,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "vendorA_trx-type1",
|
||||||
|
"transponder-mode": "mode 2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 2,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Rennes_STA",
|
||||||
|
"link-tp-id": "roadm Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 3,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_roadm Rennes_STA",
|
||||||
|
"link-tp-id": "Edfa0_roadm Rennes_STA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 4,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Rennes_STA → Stbrieuc)-F057",
|
||||||
|
"link-tp-id": "fiber (Rennes_STA → Stbrieuc)-F057"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 5,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Rennes_STA → Stbrieuc)-F057",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Rennes_STA → Stbrieuc)-F057"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 6,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "fiber (Stbrieuc → Lannion_CAS)-F056",
|
||||||
|
"link-tp-id": "fiber (Stbrieuc → Lannion_CAS)-F056"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 7,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056",
|
||||||
|
"link-tp-id": "Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 8,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "roadm Lannion_CAS",
|
||||||
|
"link-tp-id": "roadm Lannion_CAS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 9,
|
||||||
|
"num-unnum-hop": {
|
||||||
|
"node-id": "trx Lannion_CAS",
|
||||||
|
"link-tp-id": "trx Lannion_CAS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path-route-object": {
|
||||||
|
"index": 10,
|
||||||
|
"transponder": {
|
||||||
|
"transponder-type": "vendorA_trx-type1",
|
||||||
|
"transponder-mode": "mode 2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"response-id": "6",
|
||||||
|
"no-path": "Response without path information, due to failure performing the path computation"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
7
tests/data/testTopology_response_expected.csv
Normal file
7
tests/data/testTopology_response_expected.csv
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
response-id,source,destination,path_bandwidth,Pass?,nb of tsp pairs,total cost,transponder-type,transponder-mode,OSNR-0.1nm,SNR-0.1nm,SNR-bandwidth,baud rate (Gbaud),input power (dBm),path
|
||||||
|
0,trx Lorient_KMA,trx Vannes_KBE,100.0,True,1,1,Voyager,mode 1,30.84,30.84,26.75,32.0,0.0,trx Lorient_KMA | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE
|
||||||
|
1,trx Brest_KLA,trx Vannes_KBE,0.0,True,0,0,Voyager,mode 1,22.65,22.11,18.03,32.0,1.0,trx Brest_KLA | roadm Brest_KLA | Edfa0_roadm Brest_KLA | fiber (Brest_KLA → Morlaix)-F060 | east fused spans in Morlaix | fiber (Morlaix → Lannion_CAS)-F059 | west edfa in Lannion_CAS to Morlaix | roadm Lannion_CAS | east edfa in Lannion_CAS to Corlay | fiber (Lannion_CAS → Corlay)-F061 | west fused spans in Corlay | fiber (Corlay → Loudeac)-F010 | west fused spans in Loudeac | fiber (Loudeac → Lorient_KMA)-F054 | Edfa0_fiber (Loudeac → Lorient_KMA)-F054 | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE
|
||||||
|
3,trx Lannion_CAS,trx Rennes_STA,60.0,True,1,1,vendorA_trx-type1,mode 1,28.29,25.85,21.77,32.0,1.0,trx Lannion_CAS | roadm Lannion_CAS | east edfa in Lannion_CAS to Stbrieuc | fiber (Lannion_CAS → Stbrieuc)-F056 | east edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Rennes_STA)-F057 | Edfa0_fiber (Stbrieuc → Rennes_STA)-F057 | roadm Rennes_STA | trx Rennes_STA
|
||||||
|
4,trx Rennes_STA,trx Lannion_CAS,150.0,True,1,1,vendorA_trx-type1,mode 2,22.27,22.15,15.05,64.0,0.0,trx Rennes_STA | roadm Rennes_STA | Edfa1_roadm Rennes_STA | fiber (Rennes_STA → Ploermel)- | east edfa in Ploermel to Vannes_KBE | fiber (Ploermel → Vannes_KBE)- | Edfa0_fiber (Ploermel → Vannes_KBE)- | roadm Vannes_KBE | Edfa0_roadm Vannes_KBE | fiber (Vannes_KBE → Lorient_KMA)-F055 | Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055 | roadm Lorient_KMA | Edfa0_roadm Lorient_KMA | fiber (Lorient_KMA → Loudeac)-F054 | east fused spans in Loudeac | fiber (Loudeac → Corlay)-F010 | east fused spans in Corlay | fiber (Corlay → Lannion_CAS)-F061 | west edfa in Lannion_CAS to Corlay | roadm Lannion_CAS | trx Lannion_CAS
|
||||||
|
5,trx Rennes_STA,trx Lannion_CAS,20.0,True,1,1,vendorA_trx-type1,mode 2,30.79,28.77,21.68,64.0,3.0,trx Rennes_STA | roadm Rennes_STA | Edfa0_roadm Rennes_STA | fiber (Rennes_STA → Stbrieuc)-F057 | Edfa0_fiber (Rennes_STA → Stbrieuc)-F057 | fiber (Stbrieuc → Lannion_CAS)-F056 | Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056 | roadm Lannion_CAS | trx Lannion_CAS
|
||||||
|
6,,,,False,0,,,,,,,,,
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
"path-request": [
|
"path-request": [
|
||||||
{
|
{
|
||||||
"request-id": "0",
|
"request-id": "0",
|
||||||
"source": "Lorient_KMA",
|
"source": "trx Lorient_KMA",
|
||||||
"destination": "Vannes_KBE",
|
"destination": "trx Vannes_KBE",
|
||||||
"src-tp-id": "trx Lorient_KMA",
|
"src-tp-id": "trx Lorient_KMA",
|
||||||
"dst-tp-id": "trx Vannes_KBE",
|
"dst-tp-id": "trx Vannes_KBE",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -22,15 +22,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": 100000000000.0
|
"path_bandwidth": 100000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "1",
|
"request-id": "1",
|
||||||
"source": "Brest_KLA",
|
"source": "trx Brest_KLA",
|
||||||
"destination": "Vannes_KBE",
|
"destination": "trx Vannes_KBE",
|
||||||
"src-tp-id": "trx Brest_KLA",
|
"src-tp-id": "trx Brest_KLA",
|
||||||
"dst-tp-id": "trx Vannes_KBE",
|
"dst-tp-id": "trx Vannes_KBE",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -40,8 +37,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -50,66 +47,42 @@
|
|||||||
"path_bandwidth": 0
|
"path_bandwidth": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
"explicit-route-objects": {
|
||||||
"explicit-route-include-objects": [
|
"route-object-include-exclude": [
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 0,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Brest_KLA",
|
"node-id": "roadm Brest_KLA",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 1,
|
"index": 1,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Lannion_CAS",
|
"node-id": "roadm Lannion_CAS",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 2,
|
"index": 2,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Lorient_KMA",
|
"node-id": "roadm Lorient_KMA",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 3,
|
"index": 3,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm Vannes_KBE",
|
"node-id": "roadm Vannes_KBE",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -117,8 +90,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "3",
|
"request-id": "3",
|
||||||
"source": "Lannion_CAS",
|
"source": "trx Lannion_CAS",
|
||||||
"destination": "Rennes_STA",
|
"destination": "trx Rennes_STA",
|
||||||
"src-tp-id": "trx Lannion_CAS",
|
"src-tp-id": "trx Lannion_CAS",
|
||||||
"dst-tp-id": "trx Rennes_STA",
|
"dst-tp-id": "trx Rennes_STA",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -128,8 +101,8 @@
|
|||||||
"trx_mode": "mode 1",
|
"trx_mode": "mode 1",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 50000000000.0,
|
"spacing": 50000000000.0,
|
||||||
@@ -137,15 +110,12 @@
|
|||||||
"output-power": 0.0012589254117941673,
|
"output-power": 0.0012589254117941673,
|
||||||
"path_bandwidth": 60000000000.0
|
"path_bandwidth": 60000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "4",
|
"request-id": "4",
|
||||||
"source": "Rennes_STA",
|
"source": "trx Rennes_STA",
|
||||||
"destination": "Lannion_CAS",
|
"destination": "trx Lannion_CAS",
|
||||||
"src-tp-id": "trx Rennes_STA",
|
"src-tp-id": "trx Rennes_STA",
|
||||||
"dst-tp-id": "trx Lannion_CAS",
|
"dst-tp-id": "trx Lannion_CAS",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -155,8 +125,8 @@
|
|||||||
"trx_mode": "mode 2",
|
"trx_mode": "mode 2",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 75000000000.0,
|
"spacing": 75000000000.0,
|
||||||
@@ -164,15 +134,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": 150000000000.0
|
"path_bandwidth": 150000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "5",
|
"request-id": "5",
|
||||||
"source": "Rennes_STA",
|
"source": "trx Rennes_STA",
|
||||||
"destination": "Lannion_CAS",
|
"destination": "trx Lannion_CAS",
|
||||||
"src-tp-id": "trx Rennes_STA",
|
"src-tp-id": "trx Rennes_STA",
|
||||||
"dst-tp-id": "trx Lannion_CAS",
|
"dst-tp-id": "trx Lannion_CAS",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -182,8 +149,8 @@
|
|||||||
"trx_mode": "mode 2",
|
"trx_mode": "mode 2",
|
||||||
"effective-freq-slot": [
|
"effective-freq-slot": [
|
||||||
{
|
{
|
||||||
"n": "null",
|
"N": "null",
|
||||||
"m": "null"
|
"M": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"spacing": 75000000000.0,
|
"spacing": 75000000000.0,
|
||||||
@@ -191,9 +158,30 @@
|
|||||||
"output-power": 0.0019952623149688794,
|
"output-power": 0.0019952623149688794,
|
||||||
"path_bandwidth": 20000000000.0
|
"path_bandwidth": 20000000000.0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
{
|
||||||
"explicit-route-include-objects": []
|
"request-id": "6",
|
||||||
|
"source": "trx Lannion_CAS",
|
||||||
|
"destination": "trx a",
|
||||||
|
"src-tp-id": "trx Lannion_CAS",
|
||||||
|
"dst-tp-id": "trx a",
|
||||||
|
"path-constraints": {
|
||||||
|
"te-bandwidth": {
|
||||||
|
"technology": "flexi-grid",
|
||||||
|
"trx_type": "vendorA_trx-type1",
|
||||||
|
"trx_mode": "mode 2",
|
||||||
|
"effective-freq-slot": [
|
||||||
|
{
|
||||||
|
"N": "null",
|
||||||
|
"M": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"spacing": 75000000000.0,
|
||||||
|
"max-nb-of-channel": null,
|
||||||
|
"output-power": null,
|
||||||
|
"path_bandwidth": 100000000000.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -201,9 +189,8 @@
|
|||||||
{
|
{
|
||||||
"synchronization-id": "3",
|
"synchronization-id": "3",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "false",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"3",
|
"3",
|
||||||
"1"
|
"1"
|
||||||
@@ -213,9 +200,8 @@
|
|||||||
{
|
{
|
||||||
"synchronization-id": "4",
|
"synchronization-id": "4",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "false",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"4",
|
"4",
|
||||||
"5"
|
"5"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"path-request": [
|
"path-request": [
|
||||||
{
|
{
|
||||||
"request-id": "1",
|
"request-id": "1",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "g",
|
"destination": "trx g",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx g",
|
"dst-tp-id": "trx g",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -22,15 +22,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "2a",
|
"request-id": "2a",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "h",
|
"destination": "trx h",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx h",
|
"dst-tp-id": "trx h",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -49,15 +46,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "3",
|
"request-id": "3",
|
||||||
"source": "f",
|
"source": "trx f",
|
||||||
"destination": "b",
|
"destination": "trx b",
|
||||||
"src-tp-id": "trx f",
|
"src-tp-id": "trx f",
|
||||||
"dst-tp-id": "trx b",
|
"dst-tp-id": "trx b",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -76,15 +70,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "ee",
|
"request-id": "ee",
|
||||||
"source": "c",
|
"source": "trx c",
|
||||||
"destination": "f",
|
"destination": "trx f",
|
||||||
"src-tp-id": "trx c",
|
"src-tp-id": "trx c",
|
||||||
"dst-tp-id": "trx f",
|
"dst-tp-id": "trx f",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -104,36 +95,23 @@
|
|||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
"explicit-route-objects": {
|
||||||
"explicit-route-include-objects": [
|
"route-object-include-exclude": [
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 0,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm e",
|
"node-id": "roadm e",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"hop-type": "LOOSE"
|
||||||
"hop-type": "loose",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 1,
|
"index": 1,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm g",
|
"node-id": "roadm g",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -141,8 +119,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "ff",
|
"request-id": "ff",
|
||||||
"source": "c",
|
"source": "trx c",
|
||||||
"destination": "f",
|
"destination": "trx f",
|
||||||
"src-tp-id": "trx c",
|
"src-tp-id": "trx c",
|
||||||
"dst-tp-id": "trx f",
|
"dst-tp-id": "trx f",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -161,15 +139,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "10",
|
"request-id": "10",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "g",
|
"destination": "trx g",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx g",
|
"dst-tp-id": "trx g",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -188,15 +163,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "11",
|
"request-id": "11",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "h",
|
"destination": "trx h",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx h",
|
"dst-tp-id": "trx h",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -216,21 +188,15 @@
|
|||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
"explicit-route-objects": {
|
||||||
"explicit-route-include-objects": [
|
"route-object-include-exclude": [
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 0,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "bb",
|
"node-id": "bb",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -238,8 +204,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "12",
|
"request-id": "12",
|
||||||
"source": "f",
|
"source": "trx f",
|
||||||
"destination": "b",
|
"destination": "trx b",
|
||||||
"src-tp-id": "trx f",
|
"src-tp-id": "trx f",
|
||||||
"dst-tp-id": "trx b",
|
"dst-tp-id": "trx b",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -259,21 +225,15 @@
|
|||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
"explicit-route-objects": {
|
||||||
"explicit-route-include-objects": [
|
"route-object-include-exclude": [
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 0,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "trx b",
|
"node-id": "trx b",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -281,8 +241,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "13",
|
"request-id": "13",
|
||||||
"source": "c",
|
"source": "trx c",
|
||||||
"destination": "f",
|
"destination": "trx f",
|
||||||
"src-tp-id": "trx c",
|
"src-tp-id": "trx c",
|
||||||
"dst-tp-id": "trx f",
|
"dst-tp-id": "trx f",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -301,15 +261,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "14",
|
"request-id": "14",
|
||||||
"source": "c",
|
"source": "trx c",
|
||||||
"destination": "f",
|
"destination": "trx f",
|
||||||
"src-tp-id": "trx c",
|
"src-tp-id": "trx c",
|
||||||
"dst-tp-id": "trx f",
|
"dst-tp-id": "trx f",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -329,36 +286,23 @@
|
|||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
"explicit-route-objects": {
|
||||||
"explicit-route-include-objects": [
|
"route-object-include-exclude": [
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 0,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm e",
|
"node-id": "roadm e",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"hop-type": "LOOSE"
|
||||||
"hop-type": "loose",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 1,
|
"index": 1,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm g",
|
"node-id": "roadm g",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -366,8 +310,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "e:1# /",
|
"request-id": "e:1# /",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "g",
|
"destination": "trx g",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx g",
|
"dst-tp-id": "trx g",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -386,15 +330,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "b-2a",
|
"request-id": "b-2a",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "h",
|
"destination": "trx h",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx h",
|
"dst-tp-id": "trx h",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -413,15 +354,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "3a;?",
|
"request-id": "3a;?",
|
||||||
"source": "f",
|
"source": "trx f",
|
||||||
"destination": "b",
|
"destination": "trx b",
|
||||||
"src-tp-id": "trx f",
|
"src-tp-id": "trx f",
|
||||||
"dst-tp-id": "trx b",
|
"dst-tp-id": "trx b",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -440,15 +378,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "ee-s",
|
"request-id": "ee-s",
|
||||||
"source": "c",
|
"source": "trx c",
|
||||||
"destination": "f",
|
"destination": "trx f",
|
||||||
"src-tp-id": "trx c",
|
"src-tp-id": "trx c",
|
||||||
"dst-tp-id": "trx f",
|
"dst-tp-id": "trx f",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -468,36 +403,23 @@
|
|||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimizations": {
|
"explicit-route-objects": {
|
||||||
"explicit-route-include-objects": [
|
"route-object-include-exclude": [
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 0,
|
"index": 0,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm e",
|
"node-id": "roadm e",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"hop-type": "LOOSE"
|
||||||
"hop-type": "loose",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"explicit-route-usage": "route-include-ero",
|
||||||
"index": 1,
|
"index": 1,
|
||||||
"unnumbered-hop": {
|
"num-unnum-hop": {
|
||||||
"node-id": "roadm g",
|
"node-id": "roadm g",
|
||||||
"link-tp-id": "link-tp-id is not used",
|
"link-tp-id": "link-tp-id is not used",
|
||||||
"hop-type": "loose",
|
"hop-type": "LOOSE"
|
||||||
"direction": "direction is not used"
|
|
||||||
},
|
|
||||||
"label-hop": {
|
|
||||||
"te-label": {
|
|
||||||
"generic": "generic is not used",
|
|
||||||
"direction": "direction is not used"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -505,8 +427,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "ff-b",
|
"request-id": "ff-b",
|
||||||
"source": "c",
|
"source": "trx c",
|
||||||
"destination": "f",
|
"destination": "trx f",
|
||||||
"src-tp-id": "trx c",
|
"src-tp-id": "trx c",
|
||||||
"dst-tp-id": "trx f",
|
"dst-tp-id": "trx f",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -525,15 +447,12 @@
|
|||||||
"output-power": 0.001,
|
"output-power": 0.001,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "10-z",
|
"request-id": "10-z",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "g",
|
"destination": "trx g",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx g",
|
"dst-tp-id": "trx g",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -552,15 +471,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "11 g",
|
"request-id": "11 g",
|
||||||
"source": "a",
|
"source": "trx a",
|
||||||
"destination": "h",
|
"destination": "trx h",
|
||||||
"src-tp-id": "trx a",
|
"src-tp-id": "trx a",
|
||||||
"dst-tp-id": "trx h",
|
"dst-tp-id": "trx h",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -579,15 +495,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": 300000000000.0
|
"path_bandwidth": 300000000000.0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "12<",
|
"request-id": "12<",
|
||||||
"source": "f",
|
"source": "trx f",
|
||||||
"destination": "b",
|
"destination": "trx b",
|
||||||
"src-tp-id": "trx f",
|
"src-tp-id": "trx f",
|
||||||
"dst-tp-id": "trx b",
|
"dst-tp-id": "trx b",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -606,15 +519,12 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": null
|
"path_bandwidth": null
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"request-id": "12>",
|
"request-id": "12>",
|
||||||
"source": "f",
|
"source": "trx f",
|
||||||
"destination": "b",
|
"destination": "trx b",
|
||||||
"src-tp-id": "trx f",
|
"src-tp-id": "trx f",
|
||||||
"dst-tp-id": "trx b",
|
"dst-tp-id": "trx b",
|
||||||
"path-constraints": {
|
"path-constraints": {
|
||||||
@@ -633,9 +543,6 @@
|
|||||||
"output-power": null,
|
"output-power": null,
|
||||||
"path_bandwidth": null
|
"path_bandwidth": null
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"optimizations": {
|
|
||||||
"explicit-route-include-objects": []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -644,8 +551,7 @@
|
|||||||
"synchronization-id": "1",
|
"synchronization-id": "1",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "False",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"1",
|
"1",
|
||||||
"2a"
|
"2a"
|
||||||
@@ -656,8 +562,7 @@
|
|||||||
"synchronization-id": "3",
|
"synchronization-id": "3",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "False",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"3",
|
"3",
|
||||||
"1"
|
"1"
|
||||||
@@ -668,8 +573,7 @@
|
|||||||
"synchronization-id": "ff",
|
"synchronization-id": "ff",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "False",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"ff",
|
"ff",
|
||||||
"13"
|
"13"
|
||||||
@@ -680,8 +584,7 @@
|
|||||||
"synchronization-id": "13",
|
"synchronization-id": "13",
|
||||||
"svec": {
|
"svec": {
|
||||||
"relaxable": "False",
|
"relaxable": "False",
|
||||||
"link-diverse": "True",
|
"disjointness": "node link",
|
||||||
"node-diverse": "True",
|
|
||||||
"request-id-number": [
|
"request-id-number": [
|
||||||
"13",
|
"13",
|
||||||
"14"
|
"14"
|
||||||
|
|||||||
@@ -3,38 +3,48 @@
|
|||||||
# @Author: Esther Le Rouzic
|
# @Author: Esther Le Rouzic
|
||||||
# @Date: 2018-06-15
|
# @Date: 2018-06-15
|
||||||
|
|
||||||
from gnpy.core.elements import Edfa
|
""" Adding tests to check the parser non regression
|
||||||
import numpy as np
|
convention of naming of test files:
|
||||||
|
- ..._expected.json for the reference output
|
||||||
|
tests:
|
||||||
|
- generation of topology json
|
||||||
|
- reading of Eqpt sheet w and W/ power mode
|
||||||
|
- consistency of autodesign
|
||||||
|
- generation of service list based on service sheet
|
||||||
|
- writing of results in csv
|
||||||
|
- writing of results in json (same keys)
|
||||||
|
"""
|
||||||
|
|
||||||
from json import load
|
from json import load
|
||||||
|
from pathlib import Path
|
||||||
|
from os import unlink
|
||||||
|
from pandas import read_csv
|
||||||
import pytest
|
import pytest
|
||||||
from gnpy.core import network_from_json
|
|
||||||
from gnpy.core.elements import Transceiver, Fiber, Edfa
|
|
||||||
from gnpy.core.utils import lin2db, db2lin
|
|
||||||
from gnpy.core.info import SpectralInformation, Channel, Power
|
|
||||||
from gnpy.core.network import save_network, build_network
|
|
||||||
from tests.compare import compare_networks, compare_services
|
from tests.compare import compare_networks, compare_services
|
||||||
|
from gnpy.core.utils import lin2db
|
||||||
|
from gnpy.core.network import save_network, build_network
|
||||||
from gnpy.core.convert import convert_file
|
from gnpy.core.convert import convert_file
|
||||||
from gnpy.core.service_sheet import convert_service_sheet
|
from gnpy.core.service_sheet import convert_service_sheet
|
||||||
from gnpy.core.equipment import load_equipment, automatic_nch
|
from gnpy.core.equipment import load_equipment, automatic_nch
|
||||||
from gnpy.core.network import load_network
|
from gnpy.core.network import load_network
|
||||||
from pathlib import Path
|
from gnpy.core.request import (jsontocsv, requests_aggregation,
|
||||||
import filecmp
|
compute_path_dsjctn, Result_element)
|
||||||
from os import unlink
|
from examples.path_requests_run import (requests_from_json, disjunctions_from_json,
|
||||||
|
correct_route_list, correct_disjn,
|
||||||
|
compute_path_with_disjunction)
|
||||||
|
|
||||||
TEST_DIR = Path(__file__).parent
|
TEST_DIR = Path(__file__).parent
|
||||||
DATA_DIR = TEST_DIR / 'data'
|
DATA_DIR = TEST_DIR / 'data'
|
||||||
eqpt_filename = DATA_DIR / 'eqpt_config.json'
|
eqpt_filename = DATA_DIR / 'eqpt_config.json'
|
||||||
|
|
||||||
# adding tests to check the parser non regression
|
|
||||||
# convention of naming of test files:
|
|
||||||
#
|
|
||||||
# - ..._expected.json for the reference output
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('xls_input,expected_json_output', {
|
@pytest.mark.parametrize('xls_input,expected_json_output', {
|
||||||
DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_expected.json',
|
DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_expected.json',
|
||||||
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_expected.json',
|
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_expected.json',
|
||||||
}.items())
|
}.items())
|
||||||
def test_excel_json_generation(xls_input, expected_json_output):
|
def test_excel_json_generation(xls_input, expected_json_output):
|
||||||
|
""" tests generation of topology json
|
||||||
|
"""
|
||||||
convert_file(xls_input)
|
convert_file(xls_input)
|
||||||
|
|
||||||
actual_json_output = xls_input.with_suffix('.json')
|
actual_json_output = xls_input.with_suffix('.json')
|
||||||
@@ -55,20 +65,25 @@ def test_excel_json_generation(xls_input, expected_json_output):
|
|||||||
|
|
||||||
# assume xls entries
|
# assume xls entries
|
||||||
# test that the build network gives correct results in gain mode
|
# test that the build network gives correct results in gain mode
|
||||||
#
|
|
||||||
@pytest.mark.parametrize('xls_input,expected_json_output', {
|
@pytest.mark.parametrize('xls_input,expected_json_output',
|
||||||
DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
|
{DATA_DIR / 'CORONET_Global_Topology.xls':\
|
||||||
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_auto_design_expected.json',
|
DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
|
||||||
|
DATA_DIR / 'testTopology.xls':\
|
||||||
|
DATA_DIR / 'testTopology_auto_design_expected.json',
|
||||||
}.items())
|
}.items())
|
||||||
def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output):
|
def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output):
|
||||||
|
""" tests generation of topology json
|
||||||
|
test that the build network gives correct results in gain mode
|
||||||
|
"""
|
||||||
equipment = load_equipment(eqpt_filename)
|
equipment = load_equipment(eqpt_filename)
|
||||||
network = load_network(xls_input,equipment)
|
network = load_network(xls_input, equipment)
|
||||||
# in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode)
|
# in order to test the Eqpt sheet and load gain target,
|
||||||
|
# change the power-mode to False (to be in gain mode)
|
||||||
equipment['Span']['default'].power_mode = False
|
equipment['Span']['default'].power_mode = False
|
||||||
# Build the network once using the default power defined in SI in eqpt config
|
# Build the network once using the default power defined in SI in eqpt config
|
||||||
|
|
||||||
p_db = equipment['SI']['default'].power_dbm
|
p_db = equipment['SI']['default'].power_dbm
|
||||||
|
|
||||||
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
|
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
|
||||||
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
|
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
|
||||||
build_network(network, equipment, p_db, p_total_db)
|
build_network(network, equipment, p_db, p_total_db)
|
||||||
@@ -92,19 +107,23 @@ def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output)
|
|||||||
assert not results.connections.different
|
assert not results.connections.different
|
||||||
|
|
||||||
#test that autodesign creates same file as an input file already autodesigned
|
#test that autodesign creates same file as an input file already autodesigned
|
||||||
@pytest.mark.parametrize('json_input,expected_json_output', {
|
@pytest.mark.parametrize('json_input,expected_json_output',
|
||||||
DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json': DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
|
{DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json':\
|
||||||
DATA_DIR / 'testTopology_auto_design_expected.json': DATA_DIR / 'testTopology_auto_design_expected.json',
|
DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
|
||||||
|
DATA_DIR / 'testTopology_auto_design_expected.json':\
|
||||||
|
DATA_DIR / 'testTopology_auto_design_expected.json',
|
||||||
}.items())
|
}.items())
|
||||||
def test_auto_design_generation_fromjson(json_input, expected_json_output):
|
def test_auto_design_generation_fromjson(json_input, expected_json_output):
|
||||||
|
"""test that autodesign creates same file as an input file already autodesigned
|
||||||
|
"""
|
||||||
equipment = load_equipment(eqpt_filename)
|
equipment = load_equipment(eqpt_filename)
|
||||||
network = load_network(json_input,equipment)
|
network = load_network(json_input, equipment)
|
||||||
# in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode)
|
# in order to test the Eqpt sheet and load gain target,
|
||||||
|
# change the power-mode to False (to be in gain mode)
|
||||||
equipment['Span']['default'].power_mode = False
|
equipment['Span']['default'].power_mode = False
|
||||||
# Build the network once using the default power defined in SI in eqpt config
|
# Build the network once using the default power defined in SI in eqpt config
|
||||||
|
|
||||||
p_db = equipment['SI']['default'].power_dbm
|
p_db = equipment['SI']['default'].power_dbm
|
||||||
|
|
||||||
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
|
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
|
||||||
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
|
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
|
||||||
build_network(network, equipment, p_db, p_total_db)
|
build_network(network, equipment, p_db, p_total_db)
|
||||||
@@ -131,8 +150,10 @@ def test_auto_design_generation_fromjson(json_input, expected_json_output):
|
|||||||
|
|
||||||
@pytest.mark.parametrize('xls_input,expected_json_output', {
|
@pytest.mark.parametrize('xls_input,expected_json_output', {
|
||||||
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_services_expected.json',
|
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_services_expected.json',
|
||||||
}.items())
|
}.items())
|
||||||
def test_excel_service_json_generation(xls_input, expected_json_output):
|
def test_excel_service_json_generation(xls_input, expected_json_output):
|
||||||
|
""" test services creation
|
||||||
|
"""
|
||||||
convert_service_sheet(xls_input, eqpt_filename)
|
convert_service_sheet(xls_input, eqpt_filename)
|
||||||
|
|
||||||
actual_json_output = f'{str(xls_input)[:-4]}_services.json'
|
actual_json_output = f'{str(xls_input)[:-4]}_services.json'
|
||||||
@@ -150,3 +171,128 @@ def test_excel_service_json_generation(xls_input, expected_json_output):
|
|||||||
assert not results.synchronizations.missing
|
assert not results.synchronizations.missing
|
||||||
assert not results.synchronizations.extra
|
assert not results.synchronizations.extra
|
||||||
assert not results.synchronizations.different
|
assert not results.synchronizations.different
|
||||||
|
|
||||||
|
# test xls answers creation
|
||||||
|
@pytest.mark.parametrize('json_input, csv_output', {
|
||||||
|
DATA_DIR / 'testTopology_response.json': DATA_DIR / 'testTopology_response',
|
||||||
|
}.items())
|
||||||
|
def test_csv_response_generation(json_input, csv_output):
|
||||||
|
""" tests if generated csv is consistant with expected generation
|
||||||
|
same columns (order not important)
|
||||||
|
"""
|
||||||
|
with open(json_input) as jsonfile:
|
||||||
|
json_data = load(jsonfile)
|
||||||
|
equipment = load_equipment(eqpt_filename)
|
||||||
|
csv_filename = str(csv_output)+'.csv'
|
||||||
|
with open(csv_filename, 'w', encoding='utf-8') as fcsv:
|
||||||
|
jsontocsv(json_data, equipment, fcsv)
|
||||||
|
|
||||||
|
expected_csv_filename = str(csv_output)+'_expected.csv'
|
||||||
|
|
||||||
|
# expected header
|
||||||
|
# csv_header = \
|
||||||
|
# [
|
||||||
|
# 'response-id',
|
||||||
|
# 'source',
|
||||||
|
# 'destination',
|
||||||
|
# 'path_bandwidth',
|
||||||
|
# 'Pass?',
|
||||||
|
# 'nb of tsp pairs',
|
||||||
|
# 'total cost',
|
||||||
|
# 'transponder-type',
|
||||||
|
# 'transponder-mode',
|
||||||
|
# 'OSNR-0.1nm',
|
||||||
|
# 'SNR-0.1nm',
|
||||||
|
# 'SNR-bandwidth',
|
||||||
|
# 'baud rate (Gbaud)',
|
||||||
|
# 'input power (dBm)',
|
||||||
|
# 'path'
|
||||||
|
# ]
|
||||||
|
|
||||||
|
resp = read_csv(csv_filename)
|
||||||
|
unlink(csv_filename)
|
||||||
|
expected_resp = read_csv(expected_csv_filename)
|
||||||
|
resp_header = list(resp.head(0))
|
||||||
|
expected_resp_header = list(expected_resp.head(0))
|
||||||
|
# check that headers are the same
|
||||||
|
resp_header.sort()
|
||||||
|
expected_resp_header.sort()
|
||||||
|
print('headers are differents')
|
||||||
|
print(resp_header)
|
||||||
|
print(expected_resp_header)
|
||||||
|
assert resp_header == expected_resp_header
|
||||||
|
|
||||||
|
# for each header checks that the output are as expected
|
||||||
|
resp.sort_values(by=['response-id'])
|
||||||
|
expected_resp.sort_values(by=['response-id'])
|
||||||
|
|
||||||
|
for column in expected_resp:
|
||||||
|
assert list(resp[column].fillna('')) == list(expected_resp[column].fillna(''))
|
||||||
|
print('results are different')
|
||||||
|
print(list(resp[column]))
|
||||||
|
print(list(expected_resp[column]))
|
||||||
|
print(type(list(resp[column])[-1]))
|
||||||
|
|
||||||
|
def compare_response(exp_resp, act_resp):
|
||||||
|
""" False if the keys are different in the nested dicts as well
|
||||||
|
"""
|
||||||
|
print(exp_resp)
|
||||||
|
print(act_resp)
|
||||||
|
test = True
|
||||||
|
for key in act_resp.keys():
|
||||||
|
print(key)
|
||||||
|
if not key in exp_resp.keys():
|
||||||
|
print(key)
|
||||||
|
return False
|
||||||
|
if isinstance(act_resp[key], dict):
|
||||||
|
test = compare_response(exp_resp[key], act_resp[key])
|
||||||
|
if test:
|
||||||
|
for key in exp_resp.keys():
|
||||||
|
if not key in act_resp.keys():
|
||||||
|
print(key)
|
||||||
|
return False
|
||||||
|
if isinstance(exp_resp[key], dict):
|
||||||
|
test = compare_response(exp_resp[key], act_resp[key])
|
||||||
|
# at this point exp_resp and act_resp have the same keys. Check if their values are the same
|
||||||
|
for key in act_resp.keys():
|
||||||
|
if not isinstance(act_resp[key], dict):
|
||||||
|
if exp_resp[key] != act_resp[key]:
|
||||||
|
return False
|
||||||
|
return test
|
||||||
|
|
||||||
|
|
||||||
|
# test json answers creation
|
||||||
|
@pytest.mark.parametrize('xls_input, expected_response_file', {
|
||||||
|
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_response.json',
|
||||||
|
}.items())
|
||||||
|
def test_json_response_generation(xls_input, expected_response_file):
|
||||||
|
""" tests if json response is correctly generated for all combinations of requests
|
||||||
|
"""
|
||||||
|
data = convert_service_sheet(xls_input, eqpt_filename)
|
||||||
|
equipment = load_equipment(eqpt_filename)
|
||||||
|
network = load_network(xls_input, equipment)
|
||||||
|
p_db = equipment['SI']['default'].power_dbm
|
||||||
|
|
||||||
|
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
|
||||||
|
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
|
||||||
|
build_network(network, equipment, p_db, p_total_db)
|
||||||
|
rqs = requests_from_json(data, equipment)
|
||||||
|
rqs = correct_route_list(network, rqs)
|
||||||
|
dsjn = disjunctions_from_json(data)
|
||||||
|
dsjn = correct_disjn(dsjn)
|
||||||
|
rqs, dsjn = requests_aggregation(rqs, dsjn)
|
||||||
|
pths = compute_path_dsjctn(network, equipment, rqs, dsjn)
|
||||||
|
propagatedpths = compute_path_with_disjunction(network, equipment, rqs, pths)
|
||||||
|
result = []
|
||||||
|
for i, pth in enumerate(propagatedpths):
|
||||||
|
result.append(Result_element(rqs[i], pth))
|
||||||
|
temp = {
|
||||||
|
'response': [n.json for n in result]
|
||||||
|
}
|
||||||
|
# load expected result and compare keys
|
||||||
|
# (not values at this stage)
|
||||||
|
with open(expected_response_file) as jsonfile:
|
||||||
|
expected = load(jsonfile)
|
||||||
|
|
||||||
|
for i, response in enumerate(temp['response']):
|
||||||
|
assert compare_response(expected['response'][i], response)
|
||||||
|
|||||||
Reference in New Issue
Block a user