Loading src/common/tools/object_factory/EndPoint.py +2 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ def json_endpoint_ids( def json_endpoint( device_id : Dict, endpoint_uuid : str, endpoint_type : str, topology_id : Optional[Dict] = None, kpi_sample_types : List[int] = [] kpi_sample_types : List[int] = [], location : Optional[Dict] = None ): result = { Loading @@ -38,6 +38,7 @@ def json_endpoint( 'endpoint_type': endpoint_type, } if len(kpi_sample_types) > 0: result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types) if location: result['endpoint_location'] = copy.deepcopy(location) return result def json_endpoints( Loading src/common/tools/object_factory/Location.py 0 → 100644 +30 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import copy from typing import Dict, Optional def json_gps_position(latitude : float, longitude : float): return {'latitude': latitude, 'longitude': longitude} def json_location(region : Optional[str] = None, gps_position : Optional[Dict] = None): if not region and not gps_position: raise Exception('One of "region" or "gps_position" arguments must be filled') if region: result = {'region': region} else: result = {'gps_position': copy.deepcopy(gps_position)} return result src/service/requirements.in +1 −0 Original line number Diff line number Diff line Loading @@ -17,3 +17,4 @@ anytree==2.8.0 networkx==2.6.3 pydot==1.4.2 redis==4.1.2 geopy==2.3.0 src/service/service/ServiceServiceServicerImpl.py +24 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ from pathcomp.frontend.client.PathCompClient import PathCompClient from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory from .task_scheduler.TaskScheduler import TasksScheduler from .tools.ContextGetters import get_service from .tools.GeodesicDistance import gps_distance LOGGER = logging.getLogger(__name__) Loading Loading @@ -113,21 +114,42 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): if constraint.WhichOneof('constraint') == 'sla_availability': num_disjoint_paths = constraint.sla_availability.num_disjoint_paths break service_locations = [] for constraint in request.service_constraints: if constraint.WhichOneof('constraint') == 'endpoint_location': service_locations.append(constraint.endpoint_location.location) num_disjoint_paths = 1 if num_disjoint_paths is None or num_disjoint_paths == 0 else num_disjoint_paths num_expected_endpoints = num_disjoint_paths * 2 tasks_scheduler = TasksScheduler(self.service_handler_factory) if len(service_with_uuids.service_endpoint_ids) >= num_expected_endpoints: if len(service_with_uuids.service_endpoint_ids) >= num_expected_endpoints or\ len(service_locations) >= num_expected_endpoints: pathcomp_request = PathCompRequest() pathcomp_request.services.append(service_with_uuids) # pylint: disable=no-member if service_locations: context_client = ContextClient() device_list = context_client.ListDevices(Empty()) closer_endpoint_ids = [] for service_location in service_locations: distances = {} for device in device_list.devices: for endpoint in device.device_endpoints: distances[gps_distance(service_location.gps_position, endpoint.endpoint_location.gps_position)] = endpoint.endpoint_id min_distance = min(distances) closer_endpoint_ids.append(distances[min_distance]) pathcomp_request.services[0].service_endpoint_ids.extend(closer_endpoint_ids) if num_disjoint_paths is None or num_disjoint_paths in {0, 1}: pathcomp_request.shortest_path.Clear() # pylint: disable=no-member else: pathcomp_request.k_disjoint_path.num_disjoint = num_disjoint_paths # pylint: disable=no-member LOGGER.debug('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request))) LOGGER.info('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request))) pathcomp = PathCompClient() pathcomp_reply = pathcomp.Compute(pathcomp_request) pathcomp.close() Loading src/service/service/tools/GeodesicDistance.py 0 → 100644 +18 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from geopy.distance import geodesic def gps_distance(gps1, gps2): return geodesic((gps1.latitude, gps1.longitude), (gps2.latitude, gps2.longitude)).km Loading
src/common/tools/object_factory/EndPoint.py +2 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ def json_endpoint_ids( def json_endpoint( device_id : Dict, endpoint_uuid : str, endpoint_type : str, topology_id : Optional[Dict] = None, kpi_sample_types : List[int] = [] kpi_sample_types : List[int] = [], location : Optional[Dict] = None ): result = { Loading @@ -38,6 +38,7 @@ def json_endpoint( 'endpoint_type': endpoint_type, } if len(kpi_sample_types) > 0: result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types) if location: result['endpoint_location'] = copy.deepcopy(location) return result def json_endpoints( Loading
src/common/tools/object_factory/Location.py 0 → 100644 +30 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import copy from typing import Dict, Optional def json_gps_position(latitude : float, longitude : float): return {'latitude': latitude, 'longitude': longitude} def json_location(region : Optional[str] = None, gps_position : Optional[Dict] = None): if not region and not gps_position: raise Exception('One of "region" or "gps_position" arguments must be filled') if region: result = {'region': region} else: result = {'gps_position': copy.deepcopy(gps_position)} return result
src/service/requirements.in +1 −0 Original line number Diff line number Diff line Loading @@ -17,3 +17,4 @@ anytree==2.8.0 networkx==2.6.3 pydot==1.4.2 redis==4.1.2 geopy==2.3.0
src/service/service/ServiceServiceServicerImpl.py +24 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ from pathcomp.frontend.client.PathCompClient import PathCompClient from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory from .task_scheduler.TaskScheduler import TasksScheduler from .tools.ContextGetters import get_service from .tools.GeodesicDistance import gps_distance LOGGER = logging.getLogger(__name__) Loading Loading @@ -113,21 +114,42 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): if constraint.WhichOneof('constraint') == 'sla_availability': num_disjoint_paths = constraint.sla_availability.num_disjoint_paths break service_locations = [] for constraint in request.service_constraints: if constraint.WhichOneof('constraint') == 'endpoint_location': service_locations.append(constraint.endpoint_location.location) num_disjoint_paths = 1 if num_disjoint_paths is None or num_disjoint_paths == 0 else num_disjoint_paths num_expected_endpoints = num_disjoint_paths * 2 tasks_scheduler = TasksScheduler(self.service_handler_factory) if len(service_with_uuids.service_endpoint_ids) >= num_expected_endpoints: if len(service_with_uuids.service_endpoint_ids) >= num_expected_endpoints or\ len(service_locations) >= num_expected_endpoints: pathcomp_request = PathCompRequest() pathcomp_request.services.append(service_with_uuids) # pylint: disable=no-member if service_locations: context_client = ContextClient() device_list = context_client.ListDevices(Empty()) closer_endpoint_ids = [] for service_location in service_locations: distances = {} for device in device_list.devices: for endpoint in device.device_endpoints: distances[gps_distance(service_location.gps_position, endpoint.endpoint_location.gps_position)] = endpoint.endpoint_id min_distance = min(distances) closer_endpoint_ids.append(distances[min_distance]) pathcomp_request.services[0].service_endpoint_ids.extend(closer_endpoint_ids) if num_disjoint_paths is None or num_disjoint_paths in {0, 1}: pathcomp_request.shortest_path.Clear() # pylint: disable=no-member else: pathcomp_request.k_disjoint_path.num_disjoint = num_disjoint_paths # pylint: disable=no-member LOGGER.debug('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request))) LOGGER.info('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request))) pathcomp = PathCompClient() pathcomp_reply = pathcomp.Compute(pathcomp_request) pathcomp.close() Loading
src/service/service/tools/GeodesicDistance.py 0 → 100644 +18 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from geopy.distance import geodesic def gps_distance(gps1, gps2): return geodesic((gps1.latitude, gps1.longitude), (gps2.latitude, gps2.longitude)).km