add autodesign routes

Signed-off-by: manuedelf <59697943+edelfour@users.noreply.github.com>
This commit is contained in:
manuedelf
2021-01-25 23:11:05 +01:00
committed by EstherLerouzic
parent f67e9c4914
commit 459a82150b
9 changed files with 133 additions and 44 deletions

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
venv/

2
.gitignore vendored
View File

@@ -65,3 +65,5 @@ target/
# MacOS DS_store
.DS_Store
venv/

View File

@@ -10,6 +10,7 @@ COPY . /opt/application/oopt-gnpy
WORKDIR /opt/application/oopt-gnpy
RUN mkdir topology \
&& mkdir equipment \
&& mkdir autodesign \
&& pip install . \
&& chown -Rc gnpy:gnpy /opt/application/oopt-gnpy /shared/example-data
USER gnpy

View File

@@ -0,0 +1,14 @@
# coding: utf-8
class PathComputationError(Exception):
""" Exception raise for path computation error error
Attributes:
message -- explanation of the error
"""
def __init__(self, message):
self.message = message
def __str__(self):
return self.message

View File

@@ -19,10 +19,12 @@ from werkzeug.exceptions import InternalServerError
import gnpy.core.exceptions as exceptions
from gnpy.api import app
from gnpy.api.exception.exception_handler import bad_request_handler, common_error_handler
from gnpy.api.exception.path_computation_error import PathComputationError
from gnpy.api.exception.topology_error import TopologyError
from gnpy.api.service import config_service
from gnpy.api.service.encryption_service import EncryptionService
from gnpy.api.service.equipment_service import EquipmentService
from gnpy.api.service.path_request_service import PathRequestService
_logger = logging.getLogger(__name__)
@@ -49,6 +51,7 @@ def _init_app(key):
app.register_error_handler(AssertionError, bad_request_handler)
app.register_error_handler(InternalServerError, common_error_handler)
app.register_error_handler(TopologyError, bad_request_handler)
app.register_error_handler(PathComputationError, bad_request_handler)
for error_code in werkzeug.exceptions.default_exceptions:
app.register_error_handler(error_code, common_error_handler)
config = config_service.init_config()
@@ -61,6 +64,9 @@ def _configure(binder):
binder.bind(EquipmentService,
to=EquipmentService(EncryptionService(app.config['properties'].get('SECRET', 'equipment'))),
scope=singleton)
binder.bind(PathRequestService,
to=PathRequestService(EncryptionService(app.config['properties'].get('SECRET', 'equipment'))),
scope=singleton)
app.config['properties'].pop('SECRET', None)

View File

@@ -1,4 +1,5 @@
# coding: utf-8
import http
import os
from pathlib import Path
@@ -9,15 +10,18 @@ from gnpy.api.exception.equipment_error import EquipmentError
from gnpy.api.exception.topology_error import TopologyError
from gnpy.api.service import topology_service
from gnpy.api.service.equipment_service import EquipmentService
from gnpy.api.service.path_request_service import path_requests_run
from gnpy.api.service.path_request_service import PathRequestService
from gnpy.tools.json_io import _equipment_from_json, network_from_json
from gnpy.topology.request import ResultElement
PATH_COMPUTATION_BASE_PATH = '/api/v1/path-computation'
AUTODESIGN_PATH = PATH_COMPUTATION_BASE_PATH + '/<path_computation_id>/autodesign'
_examples_dir = Path(__file__).parent.parent.parent / 'example-data'
@app.route('/api/v1/path-computation', methods=['POST'])
def compute_path(equipment_service: EquipmentService):
@app.route(PATH_COMPUTATION_BASE_PATH, methods=['POST'])
def compute_path(equipment_service: EquipmentService, path_request_service: PathRequestService):
data = request.json
service = data['gnpy-api:service']
if 'gnpy-api:topology' in data:
@@ -36,10 +40,24 @@ def compute_path(equipment_service: EquipmentService):
os.path.join(_examples_dir, 'std_medium_gain_advanced_config.json'))
network = network_from_json(topology, equipment)
propagatedpths, reversed_propagatedpths, rqs = path_requests_run(service, network, equipment)
propagatedpths, reversed_propagatedpths, rqs, path_computation_id = path_request_service.path_requests_run(service,
network,
equipment)
# Generate the output
result = []
# assumes that list of rqs and list of propgatedpths have same order
for i, pth in enumerate(propagatedpths):
result.append(ResultElement(rqs[i], pth, reversed_propagatedpths[i]))
return {"result": {"response": [n.json for n in result]}}, 201
return {"result": {"response": [n.json for n in result]}}, 201, {
'location': AUTODESIGN_PATH.replace('<path_computation_id>', path_computation_id)}
@app.route(AUTODESIGN_PATH, methods=['GET'])
def get_autodesign(path_computation_id, path_request_service: PathRequestService):
return path_request_service.get_autodesign(path_computation_id), http.HTTPStatus.OK
@app.route(AUTODESIGN_PATH, methods=['DELETE'])
def delete_autodesign(path_computation_id, path_request_service: PathRequestService):
path_request_service.delete_autodesign(path_computation_id)
return '', http.HTTPStatus.NO_CONTENT

View File

@@ -35,3 +35,11 @@ def get_equipment_dir() -> str:
@return: the directory of equipments
"""
return current_app.config['properties'].get('DIRECTORY', 'equipment')
def get_autodesign_dir() -> str:
"""
Get the base dir where autodesign are saved
@return: the directory of equipments
"""
return current_app.config['properties'].get('DIRECTORY', 'autodesign')

View File

@@ -1,10 +1,16 @@
# -*- coding: utf-8 -*-
import json
import logging
import os
import uuid
import gnpy.core.ansi_escapes as ansi_escapes
from gnpy.api.exception.path_computation_error import PathComputationError
from gnpy.api.service import config_service
from gnpy.api.service.encryption_service import EncryptionService
from gnpy.core.network import build_network
from gnpy.core.utils import lin2db, automatic_nch
from gnpy.tools.json_io import requests_from_json, disjunctions_from_json
from gnpy.tools.json_io import requests_from_json, disjunctions_from_json, network_to_json
from gnpy.topology.request import (compute_path_dsjctn, requests_aggregation,
correct_json_route_list,
deduplicate_disjunctions, compute_path_with_disjunction)
@@ -13,7 +19,12 @@ from gnpy.topology.spectrum_assignment import build_oms_list, pth_assign_spectru
_logger = logging.getLogger(__name__)
def path_requests_run(service, network, equipment):
class PathRequestService:
def __init__(self, encryption_service: EncryptionService):
self.encryption = encryption_service
def path_requests_run(self, service, network, equipment):
# Build the network once using the default power defined in SI in eqpt config
# TODO power density: db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
# spacing, f_min and f_max
@@ -22,6 +33,10 @@ def path_requests_run(service, network, equipment):
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)
path_computation_identifier = str(uuid.uuid4())
autodesign_dir = config_service.get_autodesign_dir()
with(open(os.path.join(autodesign_dir, '.'.join([path_computation_identifier, 'json'])), 'wb')) as file:
file.write(self.encryption.encrypt(json.dumps(network_to_json(network)).encode()))
oms_list = build_oms_list(network, equipment)
rqs = requests_from_json(service, equipment)
@@ -59,4 +74,27 @@ def path_requests_run(service, network, equipment):
# so there can not be propagation on these nodes.
pth_assign_spectrum(pths, rqs, oms_list, reversed_pths)
return propagatedpths, reversed_propagatedpths, rqs
return propagatedpths, reversed_propagatedpths, rqs, path_computation_identifier
def get_autodesign(self, path_computation_id):
"""
Get the autodesign with id topology_id
@param path_computation_id:
@return: the autodesign in json format
"""
autodesign_dir = config_service.get_autodesign_dir()
autodesign_file = os.path.join(autodesign_dir, '.'.join([path_computation_id, 'json']))
if not os.path.exists(autodesign_file):
raise PathComputationError('Autodesign with id {} does not exist '.format(path_computation_id))
with(open(autodesign_file, 'rb')) as file:
return json.loads(self.encryption.decrypt(file.read()))
def delete_autodesign(self, path_computation_id: str):
"""
Delete autodesign with id equipment_id
@param path_computation_id:
"""
autodesign_dir = config_service.get_autodesign_dir()
autodesign_file = os.path.join(autodesign_dir, '.'.join([path_computation_id, 'json']))
if os.path.exists(autodesign_file):
os.remove(autodesign_file)

View File

@@ -1,3 +1,4 @@
[DIRECTORY]
topology: /opt/application/oopt-gnpy/topology
equipment: /opt/application/oopt-gnpy/equipment
autodesign: /opt/application/oopt-gnpy/autodesign